select.stories.jsx 92 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741
  1. import React, { useState, useRef, useEffect } from 'react';
  2. import './select.scss';
  3. import { Input, Select, Button, Icon, Avatar, Checkbox, Form, withField, Space, Tag, Switch, Divider, RadioGroup } from '../../index';
  4. import CustomTrigger from './CustomTrigger';
  5. import classNames from 'classnames';
  6. const Option = Select.Option;
  7. import { IconSearch, IconGift } from '@douyinfe/semi-icons';
  8. export default {
  9. title: 'Select',
  10. parameters: {
  11. chromatic: { disableSnapshot: true },
  12. },
  13. }
  14. let Test = () => {
  15. let [options, setOptions] = useState([1, 2, 3, 4]);
  16. function add() {
  17. let newOptions = Array.from(
  18. {
  19. length: Math.floor(Math.random() * 10),
  20. },
  21. (v, i) => i + 1
  22. );
  23. setOptions(newOptions);
  24. }
  25. let style = {
  26. width: 150,
  27. margin: 20,
  28. };
  29. let slotStyle = {
  30. backgroundColor: 'whitesmoke',
  31. height: '40px',
  32. display: 'flex',
  33. justifyContent: 'center',
  34. alignItems: 'center',
  35. borderRadius: '0 0 6px 6px',
  36. };
  37. let outSlotStyle = {
  38. backgroundColor: 'whitesmoke',
  39. height: '29px',
  40. display: 'flex',
  41. justifyContent: 'center',
  42. alignItems: 'center',
  43. cursor: 'pointer',
  44. };
  45. const click = e => {};
  46. let outSlotNode = (
  47. <div onClick={e => click(e)}>
  48. <Checkbox>sendLarkNotification</Checkbox>
  49. <div>
  50. <Button theme="solid">confirm</Button>
  51. </div>
  52. </div>
  53. );
  54. return (
  55. <>
  56. <Select
  57. style={style}
  58. dropdownClassName="test-dropdown"
  59. dropdownStyle={{
  60. width: 150,
  61. }}
  62. filter
  63. placeholder="fefe"
  64. position="rightTop"
  65. innerBottomSlot={
  66. <div style={slotStyle}>
  67. <Button
  68. size="small"
  69. style={{
  70. margin: 0,
  71. }}
  72. >
  73. 申请其他地区权限
  74. </Button>
  75. </div>
  76. }
  77. >
  78. {options.map(option => (
  79. <Option value={option} key={option} className="fefe">
  80. {option}
  81. </Option>
  82. ))}
  83. </Select>
  84. <Select
  85. style={{
  86. marginTop: 20,
  87. width: 200,
  88. }}
  89. dropdownClassName="test-dropdown"
  90. dropdownStyle={{
  91. width: 150,
  92. }}
  93. filter
  94. placeholder="fefe"
  95. position="rightTop"
  96. outerBottomSlot={outSlotNode}
  97. >
  98. {options.map(option => (
  99. <Option value={option} key={option} className="fefe">
  100. {option}
  101. </Option>
  102. ))}
  103. </Select>
  104. </>
  105. );
  106. };
  107. const AutoFocusDemo = () => {
  108. return (
  109. <>
  110. <Select
  111. autoFocus
  112. style={{
  113. width: 200,
  114. }}
  115. onFocus={() => console.log('onFocus')}
  116. onBlur={() => console.log('onBlur')}
  117. >
  118. <Option value="abc" data-test-id='douyin' data-shortcut='dy'>抖音</Option>
  119. <Option value="hotsoon" data-test-id='hotsoon'>火山</Option>
  120. <Option value="capcut" data-test-id='capcut'>剪映</Option>
  121. <Option value="duoshan" data-test-id='duoshan'>多闪</Option>
  122. <Option value="xigua" data-test-id='xigua'>西瓜视频</Option>
  123. </Select>
  124. <div className="test-div">test-div</div>
  125. </>
  126. );
  127. };
  128. export const AutoFocus = () => <AutoFocusDemo />;
  129. AutoFocus.story = {
  130. name: 'autoFocus',
  131. };
  132. export const InnerBottomSlotOuterBottomSlot = () => <Test />;
  133. InnerBottomSlotOuterBottomSlot.story = {
  134. name: 'innerBottomSlot / outerBottomSlot',
  135. };
  136. export const InnerTopSlotOuterTopSlot = () => {
  137. const slot = <div>未找到应用?</div>;
  138. return (
  139. <div>
  140. innerTopSlot
  141. <div>
  142. <Select
  143. innerTopSlot={slot}
  144. style={{
  145. width: 250,
  146. }}
  147. maxHeight={150}
  148. >
  149. <Option value="abc">抖音</Option>
  150. <Option value="hotsoon">火山</Option>
  151. <Option value="pipixia">皮皮虾</Option>
  152. <Option value="duoshan">多闪</Option>
  153. <Option value="xigua">西瓜视频</Option>
  154. </Select>
  155. </div>
  156. outerTopSlot
  157. <div>
  158. <Select
  159. outerTopSlot={slot}
  160. style={{
  161. width: 250,
  162. }}
  163. maxHeight={150}
  164. >
  165. <Option value="abc">抖音</Option>
  166. <Option value="hotsoon">火山</Option>
  167. <Option value="pipixia">皮皮虾</Option>
  168. <Option value="duoshan">多闪</Option>
  169. <Option value="xigua">西瓜视频</Option>
  170. </Select>
  171. </div>
  172. </div>
  173. );
  174. };
  175. InnerTopSlotOuterTopSlot.story = {
  176. name: 'innerTopSlot / outerTopSlot',
  177. };
  178. export const OneOptionJsxWithOtherOptionArray = () => (
  179. <Select
  180. defaultValue={'all'}
  181. style={{
  182. width: 250,
  183. }}
  184. >
  185. <Option value="all" key="all">
  186. all
  187. </Option>
  188. {[1, 2, 3].map(item => (
  189. <Option value={`type${item}`} key={item}>{`type${item}`}</Option>
  190. ))}
  191. </Select>
  192. );
  193. OneOptionJsxWithOtherOptionArray.story = {
  194. name: 'one option jsx with other option array',
  195. };
  196. let options = [
  197. {
  198. value: 'all',
  199. label: '全部',
  200. otherKey: 'all semi',
  201. },
  202. {
  203. value: 'abc',
  204. label: '抖音',
  205. otherKey: 'abc semi',
  206. },
  207. {
  208. value: 'hotsoon',
  209. label: '火山小视频',
  210. otherKey: 'hostsoom semi',
  211. },
  212. {
  213. value: 'pipixia',
  214. label: '皮皮虾',
  215. otherKey: 'pif',
  216. },
  217. {
  218. value: 'toutiao',
  219. label: '今日头条',
  220. otherKey: 'toutiao semi',
  221. },
  222. {
  223. value: 'rd',
  224. label: 'rd',
  225. otherKey: 'semi rd',
  226. },
  227. {
  228. value: 'ued',
  229. label: 'ued',
  230. otherKey: 'semi ued',
  231. },
  232. {
  233. value: 'ued',
  234. label: 'japan',
  235. otherKey: 'semi ued',
  236. },
  237. {
  238. value: '+86',
  239. label: '+86',
  240. otherKey: 'semi',
  241. },
  242. ];
  243. let longOptions = options.concat({
  244. value: 'long',
  245. label: 'Semi Design 是一个设计系统,它定义了一套中后台设计与前端基础组',
  246. });
  247. export const SelectSize = () => (
  248. <div
  249. style={{
  250. margin: 20,
  251. }}
  252. >
  253. <h4>
  254. 使用方不设width时,下拉菜单根据内容自动适配宽度(不推荐这样使用,select的宽度会动态变化)
  255. </h4>
  256. <Select
  257. defaultValue={'all'}
  258. optionList={options}
  259. style={{
  260. margin: 10,
  261. }}
  262. ></Select>
  263. <Select
  264. defaultValue={'long'}
  265. optionList={longOptions}
  266. style={{
  267. margin: 10,
  268. }}
  269. ></Select>
  270. <Select
  271. defaultValue={'abc'}
  272. size="large"
  273. optionList={options}
  274. style={{
  275. margin: 10,
  276. }}
  277. ></Select>
  278. {/* <Select defaultValue={'+86'} size="large" optionList={options} style={{margin: 10}}>
  279. </Select> */}
  280. <h4>通过style设width的</h4>
  281. 90px:{' '}
  282. <Select
  283. defaultValue={'all'}
  284. style={{
  285. width: 90,
  286. marign: 10,
  287. }}
  288. optionList={options}
  289. ></Select>
  290. 120px:{' '}
  291. <Select
  292. defaultValue={'all'}
  293. style={{
  294. width: 120,
  295. margin: 10,
  296. }}
  297. optionList={options}
  298. ></Select>
  299. 400px:{' '}
  300. <Select
  301. defaultValue={'all'}
  302. style={{
  303. width: 400,
  304. margin: 10,
  305. }}
  306. optionList={options}
  307. ></Select>
  308. <br />
  309. 100%:{' '}
  310. <Select
  311. defaultValue={'all'}
  312. style={{
  313. width: '100%',
  314. margin: 10,
  315. }}
  316. optionList={options}
  317. ></Select>
  318. <br />
  319. <h4>通过css设width的</h4>
  320. <Select defaultValue={'all'} className="test-width" optionList={options}></Select>
  321. <br />
  322. <h4>dropdownMatchSelectWidth</h4>
  323. <p>当该项设为true时,下拉菜单最小宽度会等于Select宽度(默认为true)</p>
  324. <div
  325. style={{
  326. margin: 10,
  327. }}
  328. >
  329. style方式指定90px:
  330. <Select
  331. defaultValue={'all'}
  332. optionList={options}
  333. dropdownMatchSelectWidth={true}
  334. style={{
  335. width: 90,
  336. }}
  337. />
  338. </div>
  339. <div
  340. style={{
  341. margin: 10,
  342. }}
  343. >
  344. css方式声明130px:
  345. <Select
  346. defaultValue={'all'}
  347. className="test-width"
  348. optionList={options}
  349. dropdownMatchSelectWidth={true}
  350. ></Select>
  351. </div>
  352. <div>
  353. <h4>需要强制下拉菜单与select同宽的时候</h4>
  354. <p>通过dropdownStyle覆盖min-width,将其设成与select的width同样的值</p>
  355. <Select
  356. defaultValue={'all'}
  357. style={{
  358. width: 300,
  359. margin: 10,
  360. }}
  361. dropdownStyle={{
  362. width: 300,
  363. }}
  364. optionList={options}
  365. />
  366. </div>
  367. </div>
  368. );
  369. SelectSize.story = {
  370. name: 'select size',
  371. };
  372. export const WithPrefixSuffixInsetLabelShowClearShowArrow = () => (
  373. <>
  374. <h4>prefix & suffix</h4>
  375. <Select
  376. style={{
  377. width: '250px',
  378. }}
  379. motion={false}
  380. filter
  381. optionList={options}
  382. prefix={<IconSearch />}
  383. suffix={<IconGift></IconGift>}
  384. ></Select>
  385. <Select
  386. style={{
  387. width: '250px',
  388. }}
  389. motion={false}
  390. filter
  391. optionList={options}
  392. prefix={"Prefix"}
  393. suffix={"Suffix"}
  394. ></Select>
  395. <h4>insetLabel</h4>
  396. <Select
  397. style={{
  398. width: '250px',
  399. }}
  400. optionList={options}
  401. insetLabel={'业务线'}
  402. ></Select>
  403. <h4>showClear</h4>
  404. <Select
  405. style={{
  406. width: '250px',
  407. }}
  408. optionList={options}
  409. showClear
  410. ></Select>
  411. <h4>showArrow = false</h4>
  412. <Select
  413. style={{
  414. width: '250px',
  415. }}
  416. optionList={options}
  417. showArrow={false}
  418. ></Select>
  419. <h4>defaultValue是不存在的值</h4>
  420. <Select
  421. style={{
  422. width: '250px',
  423. }}
  424. optionList={options}
  425. defaultValue="+85"
  426. ></Select>
  427. </>
  428. );
  429. WithPrefixSuffixInsetLabelShowClearShowArrow.story = {
  430. name: 'with prefix / suffix / insetLabel, showClear, showArrow',
  431. };
  432. WithPrefixSuffixInsetLabelShowClearShowArrow.parameters = {
  433. chromatic: { disableSnapshot: false },
  434. };
  435. export const WithDefaultSelected = () => (
  436. <Select
  437. style={{
  438. width: '250px',
  439. }}
  440. defaultValue={1}
  441. >
  442. <Option value={1}>opt1</Option>
  443. <Option value={2}>opt2</Option>
  444. <Option value={3}>opt3</Option>
  445. <Option value="4">opt4</Option>
  446. </Select>
  447. );
  448. WithDefaultSelected.story = {
  449. name: 'with default selected',
  450. };
  451. export const WithScrollbar = () => (
  452. <Select
  453. style={{
  454. width: '250px',
  455. }}
  456. defaultValue={1}
  457. >
  458. <Option value={1}>opt1</Option>
  459. <Option value={2}>opt2</Option>
  460. <Option value={3}>opt3</Option>
  461. <Option value="4">opt4</Option>
  462. <Option value={5}>opt5</Option>
  463. <Option value={6}>opt6</Option>
  464. <Option value={7}>opt7</Option>
  465. <Option value="8">opt8</Option>
  466. <Option value={9}>opt9</Option>
  467. <Option value={10}>opt10dfsdfsdfdsfdsfsdf</Option>
  468. <Option value={11}>opt11</Option>
  469. <Option value="12">opt12jfldsjflsdjlfldjslfjhifsdfdsfdsffdsodsjlfhjl</Option>
  470. </Select>
  471. );
  472. WithScrollbar.story = {
  473. name: 'with scrollbar',
  474. };
  475. class Link extends React.Component {
  476. get provinces() {
  477. return ['Sichuan', 'Guangdong'];
  478. }
  479. get maps() {
  480. return {
  481. Sichuan: ['Chengdu', 'Dujiangyan'],
  482. Guangdong: ['Guangzhou', 'Shenzhen', 'Dongguan'],
  483. };
  484. }
  485. constructor() {
  486. super();
  487. this.state = {
  488. provinces: this.provinces,
  489. maps: this.maps,
  490. citys: this.maps[this.provinces[0]],
  491. city: this.maps[this.provinces[0]][0],
  492. };
  493. this.provinceChange = this.provinceChange.bind(this);
  494. this.cityChange = this.cityChange.bind(this);
  495. }
  496. provinceChange(newProvince) {
  497. const { maps } = this.state;
  498. this.setState({
  499. citys: maps[newProvince],
  500. city: maps[newProvince][0],
  501. });
  502. }
  503. cityChange(city) {
  504. this.setState({
  505. city,
  506. });
  507. }
  508. render() {
  509. const { provinces, citys, city } = this.state;
  510. return (
  511. <React.Fragment>
  512. <Select
  513. style={{
  514. width: '150px',
  515. margin: '10px',
  516. }}
  517. onChange={this.provinceChange}
  518. defaultValue={provinces[0]}
  519. >
  520. {provinces.map(pro => (
  521. <Option value={pro} key={pro}>
  522. {pro}
  523. </Option>
  524. ))}
  525. </Select>
  526. <Select
  527. style={{
  528. width: '150px',
  529. margin: '10px',
  530. }}
  531. value={city}
  532. onChange={this.cityChange}
  533. >
  534. {citys.map(c => (
  535. <Option value={c} key={c}>
  536. {c}
  537. </Option>
  538. ))}
  539. </Select>
  540. </React.Fragment>
  541. );
  542. }
  543. }
  544. export const TwoSelectChangeAtTheSameTime = () => <Link />;
  545. TwoSelectChangeAtTheSameTime.story = {
  546. name: 'two select change at the same time',
  547. };
  548. export const SelectMultiple = () => (
  549. <>
  550. <Select
  551. multiple={true}
  552. max={10}
  553. style={{
  554. width: '180px',
  555. }}
  556. placeholder="fefe"
  557. >
  558. <Option value={1}>opt1</Option>
  559. <Option value={2}>opt2</Option>
  560. <Option value={3}>opt3</Option>
  561. <Option value="4">opt4</Option>
  562. <Option value={5}>opt5</Option>
  563. <Option value={6}>opt6</Option>
  564. <Option value={7}>opt7</Option>
  565. <Option value={8}>opt8</Option>
  566. </Select>
  567. <br />
  568. <br />
  569. <Select
  570. multiple={true}
  571. style={{
  572. width: '300px',
  573. }}
  574. defaultValue={[1, 2, 3]}
  575. placeholder="fefe"
  576. >
  577. <Option value={1}>opt1</Option>
  578. <Option value={2}>opt2</Option>
  579. <Option value={3}>opt3</Option>
  580. <Option value="4">opt4</Option>
  581. <Option value={5}>opt5</Option>
  582. <Option value={6}>opt6</Option>
  583. <Option value={7}>opt7</Option>
  584. <Option value={8}>opt8</Option>
  585. </Select>
  586. <br />
  587. <br />
  588. <Select
  589. multiple={true}
  590. style={{
  591. width: '300px',
  592. }}
  593. defaultValue={[1, 2, 3]}
  594. placeholder="fefe"
  595. disabled
  596. onSelect={(...res) => console.log(res)}
  597. onDeselect={(...res) => console.log(res)}
  598. >
  599. <Option value={1}>opt1</Option>
  600. <Option value={2}>opt2</Option>
  601. <Option value={3}>opt3</Option>
  602. <Option value="4">opt4</Option>
  603. <Option value={5}>opt5</Option>
  604. <Option value={6}>opt6</Option>
  605. <Option value={7}>opt7</Option>
  606. <Option value={8}>opt8</Option>
  607. </Select>
  608. <br />
  609. <br />
  610. maxTagCount = 3
  611. <br />
  612. <Select
  613. multiple={true}
  614. maxTagCount={3}
  615. style={{
  616. width: '350px',
  617. }}
  618. defaultValue={[1, 2, 3]}
  619. placeholder="fefe"
  620. insetLabel="标签"
  621. onSelect={(...res) => console.log(res)}
  622. onDeselect={(...res) => console.log(res)}
  623. >
  624. <Option value={1}>opt1</Option>
  625. <Option value={2}>opt2</Option>
  626. <Option value={3}>opt3</Option>
  627. <Option value="4">opt4</Option>
  628. <Option value={5}>opt5</Option>
  629. <Option value={6}>opt6</Option>
  630. <Option value={7}>opt7</Option>
  631. <Option value={8}>opt8</Option>
  632. </Select>
  633. <br />
  634. <br />
  635. maxTagCount = 3, showRestTagsPopover
  636. <br />
  637. <Select
  638. multiple={true}
  639. maxTagCount={3}
  640. style={{
  641. width: '350px',
  642. }}
  643. defaultValue={[1, 2, 3]}
  644. placeholder="fefe"
  645. insetLabel="标签"
  646. onSelect={(...res) => console.log(res)}
  647. onDeselect={(...res) => console.log(res)}
  648. showRestTagsPopover={true}
  649. >
  650. <Option value={1}>opt1</Option>
  651. <Option value={2}>opt2</Option>
  652. <Option value={3}>opt3</Option>
  653. <Option value="4">opt4</Option>
  654. <Option value={5}>opt5</Option>
  655. <Option value={6}>opt6</Option>
  656. <Option value={7}>opt7</Option>
  657. <Option value={8}>opt8</Option>
  658. </Select>
  659. <br />
  660. <br />
  661. maxTagCount = 3, max=5
  662. <br />
  663. <Select
  664. multiple={true}
  665. maxTagCount={3}
  666. max={5}
  667. style={{
  668. width: '350px',
  669. }}
  670. defaultValue={[1, 2, 3]}
  671. placeholder="fefe"
  672. insetLabel="标签"
  673. onSelect={(...res) => console.log(res)}
  674. onDeselect={(...res) => console.log(res)}
  675. >
  676. <Option value={1}>opt1</Option>
  677. <Option value={2}>opt2</Option>
  678. <Option value={3}>opt3</Option>
  679. <Option value="4">opt4</Option>
  680. <Option value={5}>opt5</Option>
  681. <Option value={6}>opt6</Option>
  682. <Option value={7}>opt7</Option>
  683. <Option value={8}>opt8</Option>
  684. </Select>
  685. </>
  686. );
  687. SelectMultiple.story = {
  688. name: 'select multiple',
  689. };
  690. SelectMultiple.parameters = {
  691. chromatic: { disableSnapshot: false },
  692. };
  693. export const SelectDisabled = () => (
  694. <Select
  695. disabled
  696. multiple={true}
  697. max={10}
  698. style={{
  699. width: '250px',
  700. }}
  701. >
  702. <Option value={1}>opt1</Option>
  703. <Option value={2} disabled>
  704. opt2
  705. </Option>
  706. <Option value={3}>opt3</Option>
  707. <Option value="4">opt4</Option>
  708. </Select>
  709. );
  710. SelectDisabled.story = {
  711. name: 'select disabled',
  712. };
  713. function filter(input, option) {
  714. console.log(option);
  715. return option.label.includes(input);
  716. }
  717. const spanStyle = {
  718. display: 'inline-block',
  719. marginRight: '8px',
  720. width: '16px',
  721. height: '16px',
  722. borderRadius: '50%',
  723. border: '1px solid var(--semi-color-bg-1)',
  724. };
  725. const colorOptions = [
  726. {
  727. value: 'grey-1',
  728. spanStyle: { ...spanStyle, backgroundColor: 'rgb(107, 116, 117)' },
  729. },
  730. {
  731. value: 'purple-5',
  732. spanStyle: { ...spanStyle, backgroundColor: 'rgb(158, 40, 179)' },
  733. },
  734. {
  735. value: 'pink-2',
  736. spanStyle: { ...spanStyle, backgroundColor: 'rgb(233, 30, 99)' },
  737. },
  738. {
  739. value: 'blue-3',
  740. spanStyle: { ...spanStyle, backgroundColor: 'rgb(0, 119, 250)' },
  741. },
  742. ];
  743. const alignStyle = {
  744. display: 'flex',
  745. alignItems: 'center',
  746. };
  747. const customFilter = (input, option) => {
  748. return option.value.includes(input);
  749. };
  750. export const SelectFilterSingle = () => (
  751. <div>
  752. <h5>默认筛选</h5>
  753. <Select
  754. filter
  755. style={{
  756. width: '250px',
  757. margin: 10,
  758. }}
  759. showClear
  760. autoFocus
  761. placeholder='singe filter select'
  762. onSearch={(val) => console.log(`onSearch:${val}`)}
  763. onFocus={() => console.log('onFocus')}
  764. onBlur={() => console.log('onBlur')}
  765. >
  766. <Option value={1}>opt1</Option>
  767. <Option value={2} disabled>
  768. disabled
  769. </Option>
  770. <Option value={3}>Lucy</Option>
  771. <Option value="4">bay</Option>
  772. <Option value="5">sert</Option>
  773. <Option value="6">wym</Option>
  774. <Option value="7" disabled>
  775. meno
  776. </Option>
  777. <Option value="8">opts</Option>
  778. </Select>
  779. <h5>自定义筛选函数</h5>
  780. <Select
  781. style={{
  782. width: '250px',
  783. margin: 10,
  784. }}
  785. filter={filter}
  786. showClear
  787. onBlur={() => console.log('onBlur')}
  788. onSearch={val => console.log(val)}
  789. onFocus={() => console.log('onFocus')}
  790. >
  791. <Option value={1}>opt1(value:1)</Option>
  792. <Option value={2}>mike(value:2)</Option>
  793. <Option value={3}>Lucy(value:3)</Option>
  794. <Option value={4}>bay(value:4)</Option>
  795. </Select>
  796. <h5>filter为true,但option label为node时</h5>
  797. <Select
  798. style={{
  799. width: '250px',
  800. margin: 10,
  801. }}
  802. showClear
  803. filter={customFilter}
  804. onChange={v => console.log(v)}
  805. insetLabel="insetLabel"
  806. onFocus={() => console.log('onFocus')}
  807. onBlur={() => console.log('onBlur')}
  808. onSearch={(val) => console.log(val)}
  809. >
  810. {colorOptions.map(option => (
  811. <Option value={option.value} key={option.value}>
  812. <div style={alignStyle}>
  813. <span style={option.spanStyle}></span>
  814. {option.value}
  815. </div>
  816. </Option>
  817. ))}
  818. </Select>
  819. </div>
  820. );
  821. SelectFilterSingle.story = {
  822. name: 'select filter single',
  823. };
  824. export const SelectFilterMultiple = () => (
  825. <Space>
  826. <Select
  827. filter
  828. multiple={true}
  829. style={{
  830. width: '250px',
  831. }}
  832. size='small'
  833. placeholder="fefe"
  834. >
  835. <Option value={1}>opt1</Option>
  836. <Option value={2}>opt2</Option>
  837. <Option value={3}>opt3</Option>
  838. <Option value={4}>opt4</Option>
  839. <Option value={5}>opt5</Option>
  840. <Option value={6}>opt6</Option>
  841. <Option value={7}>opt7</Option>
  842. <Option value={8}>opt8</Option>
  843. <Option value={9}>opt9</Option>
  844. <Option value={10}>opt10</Option>
  845. </Select>
  846. <Select
  847. filter
  848. multiple={true}
  849. style={{
  850. width: '250px',
  851. }}
  852. placeholder="fefe"
  853. >
  854. <Option value={1}>opt1</Option>
  855. <Option value={2}>opt2</Option>
  856. <Option value={3}>opt3</Option>
  857. <Option value={4}>opt4</Option>
  858. <Option value={5}>opt5</Option>
  859. <Option value={6}>opt6</Option>
  860. <Option value={7}>opt7</Option>
  861. <Option value={8}>opt8</Option>
  862. <Option value={9}>opt9</Option>
  863. <Option value={10}>opt10</Option>
  864. </Select>
  865. <Select
  866. filter
  867. size='large'
  868. multiple={true}
  869. style={{
  870. width: '250px',
  871. }}
  872. placeholder="fefe"
  873. >
  874. <Option value={1}>opt1</Option>
  875. <Option value={2}>opt2</Option>
  876. <Option value={3}>opt3</Option>
  877. <Option value={4}>opt4</Option>
  878. <Option value={5}>opt5</Option>
  879. <Option value={6}>opt6</Option>
  880. <Option value={7}>opt7</Option>
  881. <Option value={8}>opt8</Option>
  882. <Option value={9}>opt9</Option>
  883. <Option value={10}>opt10</Option>
  884. </Select>
  885. <Select
  886. filter
  887. multiple={true}
  888. maxTagCount={3}
  889. style={{
  890. width: '270px',
  891. }}
  892. placeholder="fefe"
  893. >
  894. <Option value={1}>opt1</Option>
  895. <Option value={2}>opt2</Option>
  896. <Option value={3}>opt3</Option>
  897. <Option value={4}>opt4</Option>
  898. <Option value={5}>opt5</Option>
  899. <Option value={6}>opt6</Option>
  900. <Option value={7}>opt7</Option>
  901. <Option value={8}>opt8</Option>
  902. </Select>
  903. </Space>
  904. );
  905. SelectFilterMultiple.story = {
  906. name: 'select filter multiple',
  907. };
  908. const OptionLabelProp = () => {
  909. const [value, setValue] = useState(1);
  910. return (
  911. <>
  912. 设置optionLabelProp属性(默认为'children')为'value'时,回填到选择框中的文本会是Option.value
  913. <br></br>
  914. <Select
  915. style={{
  916. width: '250px',
  917. }}
  918. defaultValue={1}
  919. optionLabelProp="value"
  920. >
  921. <Option value={1}>opt1</Option>
  922. <Option value={2}>opt2</Option>
  923. <Option value={3}>
  924. <span
  925. style={{
  926. color: 'pink',
  927. }}
  928. >
  929. opt3 Node
  930. </span>
  931. </Option>
  932. <Option value="4">
  933. <span
  934. style={{
  935. color: 'red',
  936. }}
  937. >
  938. testNode
  939. </span>
  940. </Option>
  941. </Select>
  942. <br />
  943. <br />
  944. <Select
  945. style={{
  946. width: '250px',
  947. }}
  948. value={value}
  949. optionLabelProp="value"
  950. onChange={setValue}
  951. >
  952. <Option value={1}>opt1</Option>
  953. <Option value={2}>opt2</Option>
  954. <Option value={3}>
  955. <span
  956. style={{
  957. color: 'pink',
  958. }}
  959. >
  960. opt3 Node
  961. </span>
  962. </Option>
  963. <Option value="4">
  964. <span
  965. style={{
  966. color: 'red',
  967. }}
  968. >
  969. testNode
  970. </span>
  971. </Option>
  972. </Select>
  973. <br />
  974. <br />
  975. <Select
  976. style={{
  977. width: '250px',
  978. }}
  979. defaultValue={1}
  980. >
  981. <Option value={1}>children Label Text 1</Option>
  982. <Option value={2}>opt2</Option>
  983. <Option value={3}>opt3</Option>
  984. <Option value="4">
  985. <span
  986. style={{
  987. color: 'red',
  988. }}
  989. >
  990. testNode
  991. </span>
  992. </Option>
  993. </Select>
  994. <Select
  995. style={{
  996. width: '250px',
  997. }}
  998. defaultValue={1}
  999. filter
  1000. optionLabelProp="value"
  1001. >
  1002. <Option value={1}>children Label Text 1</Option>
  1003. <Option value={2}>opt2</Option>
  1004. <Option value={3}>opt3</Option>
  1005. <Option value="4">
  1006. <span
  1007. style={{
  1008. color: 'red',
  1009. }}
  1010. >
  1011. testNode
  1012. </span>
  1013. </Option>
  1014. </Select>
  1015. <br />
  1016. <br />
  1017. 多选
  1018. <Select
  1019. style={{
  1020. width: '250px',
  1021. }}
  1022. multiple
  1023. filter
  1024. optionLabelProp="value"
  1025. >
  1026. <Option value={1}>children Label Text 1</Option>
  1027. <Option value={2}>opt2</Option>
  1028. <Option value={3}>opt3</Option>
  1029. <Option value="4">
  1030. <span
  1031. style={{
  1032. color: 'red',
  1033. }}
  1034. >
  1035. testNode
  1036. </span>
  1037. </Option>
  1038. </Select>
  1039. </>
  1040. );
  1041. };
  1042. class CustomRender extends React.Component {
  1043. constructor() {
  1044. super();
  1045. this.state = {
  1046. list: [
  1047. {
  1048. name: '夏可漫',
  1049. email: '[email protected]',
  1050. abbr: 'XK',
  1051. color: 'amber',
  1052. },
  1053. {
  1054. name: '申悦',
  1055. email: '[email protected]',
  1056. abbr: 'SY',
  1057. color: 'indigo',
  1058. },
  1059. {
  1060. name: '曲晨一',
  1061. email: '[email protected]',
  1062. abbr: 'CY',
  1063. color: 'blue',
  1064. },
  1065. {
  1066. name: '文嘉茂',
  1067. email: '[email protected]',
  1068. abbr: 'JM',
  1069. color: 'cyan',
  1070. },
  1071. ],
  1072. };
  1073. }
  1074. renderCustomOption(item, index) {
  1075. const optionStyle = {
  1076. display: 'flex',
  1077. };
  1078. return (
  1079. <Option key={index} value={item.name} style={optionStyle} showTick={false} {...item}>
  1080. <Avatar color={item.color} size="small">
  1081. {item.abbr}
  1082. </Avatar>
  1083. <div
  1084. style={{
  1085. marginLeft: 4,
  1086. }}
  1087. >
  1088. <p
  1089. style={{
  1090. fontSize: 14,
  1091. margin: 4,
  1092. }}
  1093. >
  1094. {item.name}
  1095. </p>
  1096. <p
  1097. style={{
  1098. margin: 4,
  1099. }}
  1100. >
  1101. {item.email}
  1102. </p>
  1103. </div>
  1104. </Option>
  1105. );
  1106. }
  1107. renderSelectedItem(optionNode) {
  1108. return (
  1109. <div>
  1110. <Avatar color={optionNode.color} size="small">
  1111. {optionNode.abbr}
  1112. </Avatar>
  1113. <span
  1114. style={{
  1115. margin: 8,
  1116. }}
  1117. >
  1118. {optionNode.email}
  1119. </span>
  1120. </div>
  1121. );
  1122. }
  1123. renderMultipleSelectedItem(optionNode) {
  1124. let content = (
  1125. <div>
  1126. <Avatar color={optionNode.color} size="small">
  1127. {optionNode.abbr}
  1128. </Avatar>
  1129. </div>
  1130. );
  1131. return {
  1132. isRenderInTag: true,
  1133. content,
  1134. };
  1135. }
  1136. renderMultipleWithoutTag(optionNode) {
  1137. let content = (
  1138. <div>
  1139. <Avatar color={optionNode.color} size="small">
  1140. {optionNode.abbr}
  1141. </Avatar>
  1142. </div>
  1143. );
  1144. return {
  1145. isRenderInTag: false,
  1146. content,
  1147. };
  1148. }
  1149. render() {
  1150. const { list } = this.state;
  1151. return (
  1152. <React.Fragment>
  1153. <Select
  1154. style={{
  1155. width: 300,
  1156. height: 40,
  1157. }}
  1158. onChange={this.provinceChange}
  1159. defaultValue={'夏可漫'}
  1160. renderSelectedItem={this.renderSelectedItem}
  1161. >
  1162. {list.map((item, index) => this.renderCustomOption(item, index))}
  1163. </Select>
  1164. <Select
  1165. style={{
  1166. width: 360,
  1167. height: 60,
  1168. marginTop: 20,
  1169. }}
  1170. onChange={this.provinceChange}
  1171. defaultValue={['夏可漫', '申悦']}
  1172. multiple
  1173. renderSelectedItem={this.renderMultipleSelectedItem}
  1174. >
  1175. {list.map((item, index) => this.renderCustomOption(item, index))}
  1176. </Select>
  1177. <Select
  1178. style={{
  1179. width: 360,
  1180. height: 60,
  1181. marginTop: 20,
  1182. }}
  1183. onChange={this.provinceChange}
  1184. defaultValue={['夏可漫', '申悦']}
  1185. multiple
  1186. renderSelectedItem={this.renderMultipleWithoutTag}
  1187. >
  1188. {list.map((item, index) => this.renderCustomOption(item, index))}
  1189. </Select>
  1190. </React.Fragment>
  1191. );
  1192. }
  1193. }
  1194. export const RenderSelectedItem = () => (
  1195. <>
  1196. renderSelectedItem
  1197. <CustomRender />
  1198. <br />
  1199. <br />
  1200. OptionLabelProp
  1201. <OptionLabelProp />
  1202. </>
  1203. );
  1204. RenderSelectedItem.story = {
  1205. name: 'renderSelectedItem',
  1206. };
  1207. RenderSelectedItem.parameters = {
  1208. chromatic: { disableSnapshot: false },
  1209. };
  1210. const ControlledSelect = () => {
  1211. const [filter, setFilter] = useState(true);
  1212. const [value, setValue] = useState('nick');
  1213. const [value2, setValue2] = useState('jerry');
  1214. const [value3, setValue3] = useState();
  1215. const [value4, setValue4] = useState(['nick']);
  1216. const [value5, setValue5] = useState();
  1217. return (
  1218. <>
  1219. <RadioGroup
  1220. type='button'
  1221. defaultValue={false}
  1222. onChange={e => setFilter(e.target.value)}
  1223. options={[
  1224. { value: true, label: 'Filter enable' },
  1225. { value: false, label: 'Filter disable' },
  1226. ]}
  1227. >
  1228. </RadioGroup>
  1229. <br />
  1230. <br />
  1231. <span>value + onChange</span>
  1232. <Select
  1233. value={value}
  1234. filter={filter}
  1235. onChange={setValue}
  1236. style={{
  1237. width: 200,
  1238. }}
  1239. >
  1240. <Option value="nick">nick</Option>
  1241. <Option value="jerry">jerry</Option>
  1242. <Option value="mark">mark</Option>
  1243. </Select>
  1244. <br />
  1245. <br />
  1246. <span>只传value,不传onChange</span>
  1247. <Select
  1248. value={value2}
  1249. filter={filter}
  1250. style={{
  1251. width: 200,
  1252. }}
  1253. >
  1254. <Option value="nick">nick</Option>
  1255. <Option value="jerry">jerry</Option>
  1256. <Option value="mark">mark</Option>
  1257. </Select>
  1258. <br />
  1259. <br />
  1260. <span>value + onChange , 多选</span>
  1261. <Select
  1262. value={value3}
  1263. onChange={setValue3}
  1264. filter={filter}
  1265. multiple
  1266. style={{
  1267. width: 200,
  1268. }}
  1269. >
  1270. <Option value="nick">nick</Option>
  1271. <Option value="jerry">jerry</Option>
  1272. <Option value="mark">mark</Option>
  1273. <Option value="nick2">nick2</Option>
  1274. <Option value="jerry2">jerry2</Option>
  1275. <Option value="mark2">mark2</Option>
  1276. </Select>
  1277. <br />
  1278. <br />
  1279. <span>value, 多选</span>
  1280. <Select
  1281. value={value4}
  1282. multiple
  1283. filter={filter}
  1284. style={{
  1285. width: 200,
  1286. }}
  1287. >
  1288. <Option value="nick">nick</Option>
  1289. <Option value="jerry">jerry</Option>
  1290. <Option value="mark">mark</Option>
  1291. </Select>
  1292. <br />
  1293. <h5>filter为true,但option label为node时</h5>
  1294. <Select
  1295. style={{
  1296. width: '250px',
  1297. }}
  1298. filter={customFilter}
  1299. insetLabel="insetLabel"
  1300. value={value5}
  1301. onChange={setValue5}
  1302. >
  1303. {colorOptions.map(option => (
  1304. <Option value={option.value} key={option.value}>
  1305. <div style={alignStyle}>
  1306. <span style={option.spanStyle}></span>
  1307. {option.value}
  1308. </div>
  1309. </Option>
  1310. ))}
  1311. </Select>
  1312. </>
  1313. );
  1314. };
  1315. export const Controlled = () => <ControlledSelect></ControlledSelect>;
  1316. Controlled.story = {
  1317. name: 'controlled',
  1318. };
  1319. const UnControlledSelect = () => {
  1320. const onChange = value => {
  1321. console.log(value);
  1322. };
  1323. return (
  1324. <>
  1325. <h5>defaultValue在list中不存在</h5>
  1326. <Select
  1327. defaultValue={90}
  1328. onChange={onChange}
  1329. style={{
  1330. width: 200,
  1331. }}
  1332. >
  1333. <Option value={20}>nick</Option>
  1334. <Option value={10}>jerry</Option>
  1335. <Option value={5}>mark</Option>
  1336. </Select>
  1337. <h5>defaultValue在list中存在</h5>
  1338. <Select
  1339. defaultValue={10}
  1340. onChange={onChange}
  1341. style={{
  1342. width: 200,
  1343. }}
  1344. >
  1345. <Option value={20}>nick</Option>
  1346. <Option value={10}>jerry</Option>
  1347. <Option value={5}>mark</Option>
  1348. </Select>
  1349. </>
  1350. );
  1351. };
  1352. export { UnControlledSelect };
  1353. UnControlledSelect.story = {
  1354. name: '非受控组件'
  1355. };
  1356. export const TestScroll = () => (
  1357. <div
  1358. style={{
  1359. marginTop: '600px',
  1360. marginBottom: '50px',
  1361. }}
  1362. >
  1363. <Select
  1364. style={{
  1365. width: '150px',
  1366. }}
  1367. >
  1368. <Option value="tony">IronMan</Option>
  1369. <Option value="Thor" disabled>
  1370. Thor
  1371. </Option>
  1372. <Option value="steve">Caption</Option>
  1373. <Option value="peter">SpiderBoy</Option>
  1374. </Select>
  1375. </div>
  1376. );
  1377. TestScroll.story = {
  1378. name: 'test scroll',
  1379. };
  1380. let optionList = [
  1381. {
  1382. value: 'tony',
  1383. label: 'Ironman',
  1384. },
  1385. {
  1386. value: 'Thor',
  1387. label: 'Thor',
  1388. },
  1389. {
  1390. value: 'steve',
  1391. label: 'Caption',
  1392. },
  1393. {
  1394. value: 'peter',
  1395. label: 'SpiderBoy',
  1396. },
  1397. ];
  1398. export const OptionList = () => (
  1399. <Select
  1400. style={{
  1401. width: '100px',
  1402. }}
  1403. optionList={optionList}
  1404. ></Select>
  1405. );
  1406. OptionList.story = {
  1407. name: 'optionList',
  1408. };
  1409. export const InsetLabel = () => (
  1410. <>
  1411. <Select
  1412. style={{
  1413. width: 300,
  1414. }}
  1415. insetLabel="主播类型"
  1416. placeholder="请选择"
  1417. optionList={optionList}
  1418. ></Select>
  1419. <Select
  1420. style={{
  1421. width: 300,
  1422. }}
  1423. multiple
  1424. insetLabel="主播类型"
  1425. optionList={optionList}
  1426. ></Select>
  1427. <Select
  1428. style={{
  1429. width: 300,
  1430. }}
  1431. filter
  1432. insetLabel="主播类型"
  1433. optionList={optionList}
  1434. ></Select>
  1435. <Select
  1436. style={{
  1437. width: 300,
  1438. }}
  1439. filter
  1440. multiple
  1441. insetLabel="主播类型"
  1442. optionList={optionList}
  1443. ></Select>
  1444. </>
  1445. );
  1446. InsetLabel.story = {
  1447. name: 'insetLabel',
  1448. };
  1449. export const ChangeOptionDynamic = () => {
  1450. function App() {
  1451. let [options, setOptions] = useState([]);
  1452. let [index, setIndex] = useState(0);
  1453. const addOption = () => {
  1454. const randomItem = optionList[index];
  1455. index = index + 1;
  1456. setIndex(index);
  1457. options = [...options, { ...randomItem }];
  1458. setOptions(options);
  1459. };
  1460. const reset = () => {
  1461. setOptions([]);
  1462. setIndex(0);
  1463. };
  1464. return (
  1465. <div>
  1466. <Select
  1467. style={{
  1468. width: '150px',
  1469. }}
  1470. defaultValue="tony"
  1471. >
  1472. {options.map((option, idx) => (
  1473. <Select.Option key={option.key || idx} value={option.value}>
  1474. {option.label}
  1475. </Select.Option>
  1476. ))}
  1477. </Select>
  1478. <h4>多选</h4>
  1479. <Select
  1480. style={{
  1481. width: '150px',
  1482. }}
  1483. multiple
  1484. defaultValue={['tony']}
  1485. >
  1486. {options.map((option, idx) => (
  1487. <Select.Option key={option.key || idx} value={option.value}>
  1488. {option.label}
  1489. </Select.Option>
  1490. ))}
  1491. </Select>
  1492. <button onClick={addOption}>add option</button>
  1493. <button onClick={reset}>reset</button>
  1494. </div>
  1495. );
  1496. }
  1497. return <App />;
  1498. };
  1499. ChangeOptionDynamic.story = {
  1500. name: 'change option dynamic',
  1501. };
  1502. let list = [
  1503. {
  1504. value: 'tony',
  1505. label: 'Ironman',
  1506. otherKey: {
  1507. role: 1,
  1508. },
  1509. },
  1510. {
  1511. value: 'Thor',
  1512. label: 'Thor',
  1513. otherKey: {
  1514. role: 2,
  1515. },
  1516. },
  1517. {
  1518. value: 'steve',
  1519. label: 'Caption',
  1520. otherKey: {
  1521. role: 3,
  1522. },
  1523. },
  1524. {
  1525. value: 'peter',
  1526. label: 'SpiderBoy',
  1527. otherKey: {
  1528. role: 4,
  1529. },
  1530. },
  1531. ];
  1532. const SearchDemo1 = () => {
  1533. const [optionList, setOptionList] = useState(list);
  1534. const [loading, setLoading] = useState(false);
  1535. const handleSearch = value => {
  1536. setLoading(true);
  1537. let length = Math.ceil(Math.random() * 10);
  1538. let result = Array.from(
  1539. {
  1540. length,
  1541. },
  1542. (v, i) => {
  1543. return {
  1544. value: value + i,
  1545. label: value + i,
  1546. otherKey: {
  1547. role: i,
  1548. },
  1549. };
  1550. }
  1551. );
  1552. setTimeout(() => {
  1553. setOptionList(result);
  1554. setLoading(false);
  1555. }, 1000);
  1556. };
  1557. const [value, setValue] = useState(optionList[0].value);
  1558. const onChange = value => {
  1559. console.log(value);
  1560. setValue(value);
  1561. };
  1562. return (
  1563. <div>
  1564. 受控:
  1565. <Select
  1566. filter
  1567. style={{
  1568. width: '150px',
  1569. }}
  1570. onSearch={v => handleSearch(v)}
  1571. optionList={optionList}
  1572. value={value}
  1573. loading={loading}
  1574. showClear
  1575. onChange={onChange}
  1576. ></Select>
  1577. 非受控:
  1578. <Select
  1579. style={{
  1580. width: '150px',
  1581. }}
  1582. filter
  1583. showClear
  1584. onSearch={v => handleSearch(v)}
  1585. optionList={optionList}
  1586. loading={loading}
  1587. onChange={onChange}
  1588. ></Select>
  1589. 多选非受控
  1590. <Select
  1591. style={{
  1592. width: '150px',
  1593. }}
  1594. showClear
  1595. filter
  1596. multiple
  1597. onSearch={v => handleSearch(v)}
  1598. optionList={optionList}
  1599. loading={loading}
  1600. onChange={onChange}
  1601. ></Select>
  1602. </div>
  1603. );
  1604. };
  1605. import debounce from 'lodash/debounce';
  1606. class SearchDemo2 extends React.Component {
  1607. constructor() {
  1608. super();
  1609. this.state = {
  1610. loading: false,
  1611. optionList: [
  1612. {
  1613. value: 'abc',
  1614. label: '抖音',
  1615. type: 1,
  1616. },
  1617. {
  1618. value: 'hotsoon',
  1619. label: '火山小视频',
  1620. type: 2,
  1621. },
  1622. {
  1623. value: 'pipixia',
  1624. label: '皮皮虾',
  1625. type: 3,
  1626. },
  1627. {
  1628. value: 'toutiao',
  1629. label: '今日头条',
  1630. type: 4,
  1631. },
  1632. ],
  1633. value: [],
  1634. };
  1635. this.handleSearch = debounce(this.handleSearch, 800).bind(this);
  1636. this.onChange = this.onChange.bind(this);
  1637. this.customRender = this.customRender.bind(this);
  1638. }
  1639. handleSearch(inputValue) {
  1640. this.setState({
  1641. loading: true,
  1642. });
  1643. let length = Math.ceil(Math.random() * 100);
  1644. let result = Array.from(
  1645. {
  1646. length,
  1647. },
  1648. (v, i) => {
  1649. return {
  1650. value: inputValue + i,
  1651. label: 'label' + i,
  1652. type: i + 1,
  1653. };
  1654. }
  1655. );
  1656. setTimeout(() => {
  1657. this.setState({
  1658. optionList: result,
  1659. loading: false,
  1660. });
  1661. }, 2000);
  1662. }
  1663. onChange(value) {
  1664. this.setState({
  1665. value,
  1666. });
  1667. console.log(value);
  1668. }
  1669. customRender(optionNode) {
  1670. return optionNode.value + optionNode.label;
  1671. }
  1672. render() {
  1673. const { loading, optionList, value } = this.state;
  1674. return (
  1675. <div>
  1676. <Select
  1677. style={{
  1678. width: 150,
  1679. }}
  1680. showClear
  1681. filter
  1682. labelInValue
  1683. onSearch={this.handleSearch}
  1684. optionList={optionList}
  1685. loading={loading}
  1686. onChange={this.onChange}
  1687. placeholder="请选择"
  1688. ></Select>
  1689. <br />
  1690. <br />
  1691. <Select
  1692. style={{
  1693. width: 180,
  1694. }}
  1695. filter // labelInValue
  1696. showClear
  1697. multiple
  1698. value={value}
  1699. renderSelectedItem={this.customRender}
  1700. onSearch={this.handleSearch}
  1701. optionList={optionList}
  1702. loading={loading}
  1703. onChange={this.onChange}
  1704. placeholder="请选择"
  1705. ></Select>
  1706. </div>
  1707. );
  1708. }
  1709. }
  1710. export const Search = () => (
  1711. <>
  1712. <SearchDemo1 />
  1713. <SearchDemo2 />
  1714. </>
  1715. );
  1716. Search.story = {
  1717. name: 'search',
  1718. };
  1719. export const IncomeDetail = ({ config = {}, params = {} }) => {
  1720. const [detailList, setDetailList] = useState([]);
  1721. const [hasMore, setHasMore] = useState(true);
  1722. const [loading, setLoading] = useState();
  1723. let lock;
  1724. const fetchData = (outParams = {}) => {
  1725. if (lock) {
  1726. return;
  1727. }
  1728. setLoading(true); // 参数
  1729. // 请求
  1730. fetch({
  1731. url: URL.user_profit,
  1732. method: 'get',
  1733. baseURL: config.webcast_host,
  1734. params,
  1735. })
  1736. .then(res => {
  1737. lock = false;
  1738. setLoading(false);
  1739. console.log('++++', data);
  1740. })
  1741. .catch(() => {
  1742. setLoading(false);
  1743. Toast.show('网络异常,请稍后重试');
  1744. });
  1745. };
  1746. useEffect(fetchData, []); // 监听滚动设置吸顶 以及加载更多
  1747. useEffect(() => {
  1748. window.addEventListener('scroll', function() {
  1749. // 加载更多
  1750. const scrollY = window.scrollY;
  1751. const scrollHeight = document.documentElement.scrollHeight;
  1752. const screenHeight = screen.height;
  1753. if (!loading && hasMore && scrollY + screenHeight + 300 > scrollHeight) {
  1754. fetchData();
  1755. }
  1756. });
  1757. }, [detailList.length]);
  1758. return (
  1759. <div>
  1760. <Select></Select>
  1761. </div>
  1762. );
  1763. };
  1764. export const AllowCreate = () => (
  1765. <Select
  1766. style={{
  1767. width: 500,
  1768. }}
  1769. optionList={optionList}
  1770. allowCreate={true}
  1771. multiple={true}
  1772. filter={true}
  1773. onChange={v => console.log(v)}
  1774. ></Select>
  1775. );
  1776. AllowCreate.story = {
  1777. name: 'allowCreate',
  1778. };
  1779. export const AllowCreateCustomRender = () => (
  1780. <Select
  1781. style={{
  1782. width: 500,
  1783. }}
  1784. optionList={optionList}
  1785. allowCreate={true}
  1786. multiple={true}
  1787. filter={true}
  1788. onChange={v => console.log(v)}
  1789. renderCreateItem={v => `semi: ${v}`}
  1790. ></Select>
  1791. );
  1792. AllowCreateCustomRender.story = {
  1793. name: 'allowCreate custom render',
  1794. };
  1795. let AllowCreateControlledDemo = () => {
  1796. let [value, setValue] = useState();
  1797. const optionList = [
  1798. {
  1799. value: 'abc',
  1800. label: '抖音',
  1801. },
  1802. {
  1803. value: 'hotsoon',
  1804. label: '火山小视频',
  1805. },
  1806. {
  1807. value: 'pipixia',
  1808. label: '皮皮虾',
  1809. },
  1810. {
  1811. value: 'toutiao',
  1812. label: '今日头条',
  1813. },
  1814. ];
  1815. const [list, setList] = useState(optionList);
  1816. const handleSelect = v => {
  1817. var lastOne = v[v.length - 1];
  1818. if (lastOne && list.findIndex(item => item.value === lastOne) == -1) {
  1819. list.push({
  1820. value: lastOne,
  1821. label: lastOne,
  1822. });
  1823. }
  1824. setList(list);
  1825. setValue(v);
  1826. };
  1827. return (
  1828. <Select
  1829. style={{
  1830. width: 400,
  1831. }}
  1832. optionList={list}
  1833. allowCreate={true}
  1834. multiple={true}
  1835. filter={true}
  1836. value={value}
  1837. onChange={handleSelect}
  1838. ></Select>
  1839. );
  1840. };
  1841. const AllowCreateDemo = () => {
  1842. let [value, setValue] = useState();
  1843. const optionList = [
  1844. {
  1845. value: 'abc',
  1846. label: '抖音',
  1847. },
  1848. {
  1849. value: 'hotsoon',
  1850. label: '火山小视频',
  1851. },
  1852. {
  1853. value: 'pipixia',
  1854. label: '皮皮虾',
  1855. },
  1856. {
  1857. value: 'toutiao',
  1858. label: '今日头条',
  1859. },
  1860. ];
  1861. const [list, setList] = useState(optionList);
  1862. const handleSelect = v => {
  1863. var lastOne = v[v.length - 1];
  1864. if (lastOne && list.findIndex(item => item.value === lastOne) == -1) {
  1865. list.push({
  1866. value: lastOne,
  1867. label: lastOne,
  1868. });
  1869. }
  1870. setList(list); // setValue(v)
  1871. };
  1872. return (
  1873. <Select
  1874. style={{
  1875. width: 400,
  1876. }}
  1877. optionList={list}
  1878. defaultValue={['abc', 'hotsoon']}
  1879. allowCreate={true}
  1880. multiple={true}
  1881. filter={true}
  1882. onChange={handleSelect}
  1883. ></Select>
  1884. );
  1885. };
  1886. export const AllowCreateWithDefaultValue = () => <AllowCreateDemo />;
  1887. AllowCreateWithDefaultValue.story = {
  1888. name: 'allowCreate with defaultValue',
  1889. };
  1890. class HideDemo extends React.Component {
  1891. constructor(props) {
  1892. super(props);
  1893. this.state = {
  1894. optionList: [
  1895. {
  1896. value: 'abc',
  1897. label: '抖音',
  1898. },
  1899. {
  1900. value: 'hotsoon',
  1901. label: '火山小视频',
  1902. },
  1903. {
  1904. value: 'pipixia',
  1905. label: '皮皮虾',
  1906. },
  1907. {
  1908. value: 'toutiao',
  1909. label: '今日头条',
  1910. },
  1911. ],
  1912. selectedItems: [],
  1913. };
  1914. this.onChange = this.onChange.bind(this);
  1915. }
  1916. onChange(selectedItems) {
  1917. this.setState({
  1918. selectedItems,
  1919. });
  1920. }
  1921. render() {
  1922. let { optionList, selectedItems } = this.state;
  1923. let filterOptions = optionList.filter(option => !selectedItems.includes(option.value));
  1924. return (
  1925. <Select
  1926. value={selectedItems}
  1927. multiple
  1928. style={{
  1929. width: 300,
  1930. }}
  1931. onChange={this.onChange}
  1932. optionList={filterOptions}
  1933. ></Select>
  1934. );
  1935. }
  1936. }
  1937. export const AutoHiddenSelectedItem = () => <HideDemo></HideDemo>;
  1938. AutoHiddenSelectedItem.story = {
  1939. name: 'auto hidden selected item',
  1940. };
  1941. class CustomCreate extends React.Component {
  1942. constructor(props) {
  1943. super(props);
  1944. this.state = {
  1945. optionList: [
  1946. {
  1947. value: 'abc',
  1948. label: '抖音',
  1949. },
  1950. {
  1951. value: 'hotsoon',
  1952. label: '火山小视频',
  1953. },
  1954. {
  1955. value: 'pipixia',
  1956. label: '皮皮虾',
  1957. },
  1958. {
  1959. value: 'toutiao',
  1960. label: '今日头条',
  1961. },
  1962. {
  1963. value: 0,
  1964. label: 0,
  1965. },
  1966. ],
  1967. selectedItems: ['fefe'],
  1968. };
  1969. this.onChange = this.onChange.bind(this);
  1970. this.customRender = this.customRender.bind(this);
  1971. this.search = this.search.bind(this);
  1972. }
  1973. onChange(selectedItems) {
  1974. console.log(selectedItems); // this.setState({ selectedItems, optionList: [] });
  1975. this.setState({
  1976. selectedItems,
  1977. }); // this.setState({ optionList: [] });
  1978. }
  1979. customRender(v) {
  1980. return (
  1981. <>
  1982. <span>label:{v.label}</span>
  1983. <span>value:{v.value}</span>
  1984. </>
  1985. );
  1986. }
  1987. customCreate(inputValue, isFocus) {
  1988. let style = {
  1989. padding: 12,
  1990. cursor: 'pointer',
  1991. backgroundColor: isFocus ? 'var(--semi-color-fill-0)' : '#FFF',
  1992. };
  1993. return <div style={style}>{'create' + inputValue}</div>;
  1994. }
  1995. search(inputValue) {
  1996. let length = Math.ceil(Math.random() * 10);
  1997. let result = Array.from(
  1998. {
  1999. length,
  2000. },
  2001. (v, i) => {
  2002. return {
  2003. value: inputValue + i,
  2004. label: inputValue + i,
  2005. type: i + 1,
  2006. };
  2007. }
  2008. );
  2009. console.log(result); // result = result.concat(selectedOption);
  2010. this.setState({
  2011. optionList: result,
  2012. });
  2013. }
  2014. render() {
  2015. let { optionList, selectedItems } = this.state;
  2016. return (
  2017. <>
  2018. <Select
  2019. defaultValue={['abc']}
  2020. filter
  2021. style={{
  2022. width: 300,
  2023. }}
  2024. multiple
  2025. optionList={optionList}
  2026. onSearch={this.search}
  2027. onChange={this.onChange}
  2028. emptyContent={null} // onChangeWithObject
  2029. ></Select>
  2030. </>
  2031. );
  2032. }
  2033. }
  2034. export const _CustomCreate = () => <CustomCreate></CustomCreate>;
  2035. _CustomCreate.story = {
  2036. name: 'CustomCreate',
  2037. };
  2038. class OptionGroupDemo extends React.Component {
  2039. constructor(props) {
  2040. super(props);
  2041. this.state = {
  2042. groups: [
  2043. {
  2044. label: 'Asia',
  2045. children: [
  2046. {
  2047. label: 'China',
  2048. value: 'zhongguo',
  2049. },
  2050. {
  2051. label: 'Korea',
  2052. value: 'hanguo',
  2053. },
  2054. ],
  2055. },
  2056. {
  2057. label: 'Europe',
  2058. children: [
  2059. {
  2060. label: 'Germany',
  2061. value: 'deguo',
  2062. },
  2063. {
  2064. label: 'France',
  2065. value: 'faguo',
  2066. },
  2067. ],
  2068. },
  2069. {
  2070. label: 'Other',
  2071. children: [
  2072. {
  2073. label: 'vf',
  2074. value: 'Sourth',
  2075. },
  2076. ],
  2077. },
  2078. ],
  2079. };
  2080. }
  2081. renderGroup(group, index) {
  2082. const options = group.children.map(option => (
  2083. <Select.Option value={option.value} label={option.label} key={option.label} data-test-id={option.label} />
  2084. ));
  2085. return <Select.OptGroup key={`${index}-${group.label}`} label={group.label} data-test-id={group.label}>{options}</Select.OptGroup>;
  2086. }
  2087. render() {
  2088. const { groups } = this.state;
  2089. return (
  2090. <>
  2091. <Select
  2092. placeholder="with key"
  2093. id='with-key'
  2094. style={{
  2095. width: 180,
  2096. }}
  2097. filter
  2098. showClear
  2099. >
  2100. {groups.map((group, index) => this.renderGroup(group, index))}
  2101. </Select>
  2102. <Select
  2103. filter={(sugInput, option) => {
  2104. let label = option.label.toUpperCase();
  2105. let sug = sugInput.toUpperCase();
  2106. return label.includes(sug);
  2107. }}
  2108. showClear
  2109. id='without-key'
  2110. style={{ width: "180px" }}
  2111. placeholder="without key"
  2112. >
  2113. <Select.OptGroup label="Group1">
  2114. <Select.Option value="douyin">
  2115. Douyin
  2116. </Select.Option>
  2117. <Select.Option value="ulikecam">
  2118. Ulikecam
  2119. </Select.Option>
  2120. </Select.OptGroup>
  2121. <Select.OptGroup label="Group2">
  2122. <Select.Option value="jianying">
  2123. Capcut
  2124. </Select.Option>
  2125. <Select.Option value="xigua">
  2126. Xigua
  2127. </Select.Option>
  2128. </Select.OptGroup>
  2129. </Select>
  2130. </>
  2131. );
  2132. }
  2133. }
  2134. export const SelectOptionGroup = () => <OptionGroupDemo />;
  2135. const BlurDemo = () => {
  2136. const onBlur = (value, e) => {
  2137. console.log(value);
  2138. console.log(e);
  2139. console.log('onBlur');
  2140. };
  2141. const onFocus = (value, e) => {
  2142. console.log(value);
  2143. console.log(e);
  2144. console.log('onFocus');
  2145. };
  2146. return (
  2147. <>
  2148. <Select
  2149. filter
  2150. placeholder=""
  2151. style={{
  2152. width: 180,
  2153. }}
  2154. onBlur={onBlur}
  2155. onFocus={onFocus}
  2156. >
  2157. <Select.Option value="zhongguo">China</Select.Option>
  2158. <Select.Option value="hanguo">Korea</Select.Option>
  2159. <Select.Option value="deguo">Germany</Select.Option>
  2160. <Select.Option value="faguo">France</Select.Option>
  2161. </Select>
  2162. <br />
  2163. <br />
  2164. <br />
  2165. <Select
  2166. filter
  2167. placeholder="多选"
  2168. style={{
  2169. width: 180,
  2170. }}
  2171. onBlur={onBlur}
  2172. onFocus={onFocus}
  2173. multiple
  2174. >
  2175. <Select.Option value="zhongguo">China</Select.Option>
  2176. <Select.Option value="hanguo">Korea</Select.Option>
  2177. <Select.Option value="deguo">Germany</Select.Option>
  2178. <Select.Option value="faguo">France</Select.Option>
  2179. </Select>
  2180. </>
  2181. );
  2182. };
  2183. export const SelectOnBlurOnFocus = () => <BlurDemo></BlurDemo>;
  2184. SelectOnBlurOnFocus.story = {
  2185. name: 'Select onBlur/onFocus',
  2186. };
  2187. const AutoAdjustOverflowDemo = () => {
  2188. const [list, setList] = useState([
  2189. {
  2190. value: 'abc',
  2191. label: '1111',
  2192. },
  2193. {
  2194. value: 'hotsoon',
  2195. label: '1112',
  2196. },
  2197. {
  2198. value: 'pipixia',
  2199. label: '1113',
  2200. },
  2201. {
  2202. value: 'toutiao',
  2203. label: '1114',
  2204. },
  2205. ]);
  2206. const onSearch = () => {
  2207. let newList = Array.from(
  2208. {
  2209. length: Math.floor(Math.random() * 10),
  2210. },
  2211. (v, i) => {
  2212. return {
  2213. value: i,
  2214. label: i,
  2215. };
  2216. }
  2217. );
  2218. setList(newList);
  2219. console.log(newList);
  2220. };
  2221. return (
  2222. <div
  2223. style={{
  2224. height: 180,
  2225. margin: 250,
  2226. border: '1px solid pink',
  2227. }}
  2228. >
  2229. <Select
  2230. optionList={list}
  2231. filter={true}
  2232. remote={true}
  2233. onSearch={onSearch}
  2234. style={{
  2235. width: 200,
  2236. }}
  2237. multiple
  2238. />
  2239. </div>
  2240. );
  2241. };
  2242. export const AutoAdjustOverflow = () => <AutoAdjustOverflowDemo></AutoAdjustOverflowDemo>;
  2243. AutoAdjustOverflow.story = {
  2244. name: 'autoAdjustOverflow',
  2245. };
  2246. const AllowCreateWithFilter = () => {
  2247. const [list, setList] = useState([
  2248. {
  2249. value: 'abc',
  2250. label: 'abc',
  2251. otherKey: 'abc',
  2252. },
  2253. {
  2254. value: 'hotsoon',
  2255. label: 'hotsoon',
  2256. otherKey: 'efg',
  2257. },
  2258. {
  2259. value: 'pipixia',
  2260. label: 'pipixia',
  2261. otherKey: 'hij',
  2262. },
  2263. {
  2264. value: 'toutiao',
  2265. label: 'toutiao',
  2266. otherKey: 'klm',
  2267. },
  2268. ]);
  2269. const filter = (sugInput, option) => {
  2270. let compareKey = option.otherKey ? option.otherKey.toUpperCase() : '';
  2271. let sug = sugInput.toUpperCase();
  2272. return compareKey.includes(sug);
  2273. };
  2274. return (
  2275. <div
  2276. style={{
  2277. height: 180,
  2278. margin: 250,
  2279. }}
  2280. >
  2281. <Select
  2282. optionList={list}
  2283. multiple
  2284. filter={filter}
  2285. style={{
  2286. width: 200,
  2287. }}
  2288. allowCreate
  2289. />
  2290. </div>
  2291. );
  2292. };
  2293. export const FilterAllowCreate = () => <AllowCreateWithFilter></AllowCreateWithFilter>;
  2294. FilterAllowCreate.story = {
  2295. name: 'Filter + allowCreate',
  2296. };
  2297. const SelectRefDemo = () => {
  2298. const ref = useRef();
  2299. const secondRef = useRef();
  2300. const [open, setOpen] = useState(false);
  2301. const list = [
  2302. {
  2303. value: 'abc',
  2304. label: 'Abc',
  2305. },
  2306. {
  2307. value: 'hotsoon',
  2308. label: 'Hotsoon',
  2309. },
  2310. {
  2311. value: 'pipixia',
  2312. label: 'Pipixia',
  2313. },
  2314. {
  2315. value: 'toutiao',
  2316. label: 'TooBuzz',
  2317. },
  2318. ];
  2319. const change = () => {
  2320. if (!open) {
  2321. ref.current.open();
  2322. setOpen(true);
  2323. } else {
  2324. ref.current.close();
  2325. setOpen(false);
  2326. }
  2327. };
  2328. const focus = () => {
  2329. ref.current.focus();
  2330. };
  2331. const clearInput = () => {
  2332. ref.current.clearInput();
  2333. };
  2334. const deselectAll = () => {
  2335. ref.current.deselectAll();
  2336. };
  2337. const selectAll = () => {
  2338. ref.current.selectAll();
  2339. };
  2340. return (
  2341. <>
  2342. <h4>onChangeWithObject = false</h4>
  2343. <Select
  2344. innerBottomSlot={
  2345. <div>
  2346. <Space>
  2347. <Button onClick={change}>close</Button>
  2348. <Button onClick={clearInput}>clearInput</Button>
  2349. <Button onClick={deselectAll}>deselectAll</Button>
  2350. <Button onClick={selectAll}>selectAll</Button>
  2351. </Space>
  2352. </div>
  2353. }
  2354. ref={ref}
  2355. onChange={e => console.log(e)}
  2356. placeholder="Business line"
  2357. style={{
  2358. width: 180,
  2359. }}
  2360. optionList={list}
  2361. filter
  2362. multiple
  2363. ></Select>
  2364. <Space>
  2365. <Button onClick={change}>open</Button>
  2366. <Button onClick={focus}>focus</Button>
  2367. <Button onClick={clearInput}>clearInput</Button>
  2368. <Button onClick={deselectAll}>deselectAll</Button>
  2369. <Button onClick={selectAll}>selectAll</Button>
  2370. </Space>
  2371. <h4
  2372. style={{
  2373. marginTop: 20,
  2374. }}
  2375. >
  2376. onChangeWithObject = true
  2377. </h4>
  2378. <Select
  2379. innerBottomSlot={
  2380. <div>
  2381. <Space></Space>
  2382. </div>
  2383. }
  2384. onChange={e => console.log(e)}
  2385. onChangeWithObject
  2386. ref={secondRef}
  2387. placeholder="Business line"
  2388. style={{
  2389. width: 180,
  2390. }}
  2391. optionList={list}
  2392. filter
  2393. multiple
  2394. ></Select>
  2395. <Space>
  2396. <Button onClick={() => secondRef.current.deselectAll()}>deselectAll</Button>
  2397. <Button onClick={() => secondRef.current.selectAll()}>selectAll</Button>
  2398. </Space>
  2399. </>
  2400. );
  2401. };
  2402. export const Ref = () => <SelectRefDemo />;
  2403. Ref.story = {
  2404. name: 'ref',
  2405. };
  2406. export const CustomTriggerDemo = () => <CustomTrigger />;
  2407. CustomTriggerDemo.story = {
  2408. name: 'custom trigger'
  2409. }
  2410. class VirtualizeClassDemo extends React.Component {
  2411. constructor(props) {
  2412. super(props);
  2413. // this.handleSearch = this.handleSearch.bind(this);
  2414. let newOptions = Array.from({ length: 1000 }, (v, i) => ({ label: `o-${i}`, value: `v-${v}-${i}` }));
  2415. this.state = {
  2416. optionList: newOptions,
  2417. };
  2418. }
  2419. render() {
  2420. let { groups, optionList } = this.state;
  2421. let virtualize = {
  2422. height: 300,
  2423. widht: '100%',
  2424. itemSize: 36,
  2425. };
  2426. return (
  2427. <>
  2428. <Select
  2429. placeholder=""
  2430. style={{ width: 180 }}
  2431. filter
  2432. onSearch={this.handleSearch}
  2433. virtualize={virtualize}
  2434. optionList={optionList}
  2435. ></Select>
  2436. </>
  2437. );
  2438. }
  2439. }
  2440. export const VirtualizeDemo = () => <VirtualizeClassDemo />;
  2441. VirtualizeDemo.story = {
  2442. name: 'virtualize select'
  2443. }
  2444. const SelectPosition = () => {
  2445. return (
  2446. <div
  2447. style={{
  2448. height: 500,
  2449. border: '1px solid red',
  2450. overflow: 'auto',
  2451. }}
  2452. >
  2453. <p>p</p>
  2454. <p>p</p>
  2455. <p>p</p>
  2456. <p>p</p>
  2457. <p>p</p>
  2458. <p>p</p>
  2459. <p>p</p>
  2460. <p>p</p>
  2461. <p>p</p>
  2462. <p>p</p>
  2463. <p>p</p>
  2464. <p>p</p>
  2465. <p>p</p>
  2466. <p>p</p>
  2467. <p>p</p>
  2468. <p>p</p>
  2469. <p>p</p>
  2470. <p>p</p>
  2471. <p>p</p>
  2472. <p>p</p>
  2473. <p>p</p>
  2474. <p>p</p>
  2475. <p>p</p>
  2476. <Select
  2477. defaultValue="abc"
  2478. style={{
  2479. width: 120,
  2480. }}
  2481. >
  2482. <Option value="abc">抖音</Option>
  2483. <Option value="hotsoon">火山</Option>
  2484. <Option value="pipixia" disabled>
  2485. 皮皮虾
  2486. </Option>
  2487. <Option value="xigua">西瓜视频</Option>
  2488. </Select>
  2489. <p>p</p>
  2490. <p>p</p>
  2491. <p>p</p>
  2492. <p>p</p>
  2493. <p>p</p>
  2494. <p>p</p>
  2495. <p>p</p>
  2496. <p>p</p>
  2497. <p>p</p>
  2498. <p>p</p>
  2499. <p>p</p>
  2500. <p>p</p>
  2501. <p>p</p>
  2502. <p>p</p>
  2503. <p>p</p>
  2504. <p>p</p>
  2505. <p>p</p>
  2506. <p>p</p>
  2507. <p>p</p>
  2508. <p>p</p>
  2509. <p>p</p>
  2510. <p>p</p>
  2511. <p>p</p>
  2512. <p>p</p>
  2513. <p>p</p>
  2514. <p>p</p>
  2515. <p>p</p>
  2516. <p>p</p>
  2517. <p>p</p>
  2518. <p>p</p>
  2519. <p>p</p>
  2520. <p>p</p>
  2521. <p>p</p>
  2522. <p>p</p>
  2523. <p>p</p>
  2524. <p>p</p>
  2525. <p>p</p>
  2526. <p>p</p>
  2527. <p>p</p>
  2528. <p>p</p>
  2529. <p>p</p>
  2530. <p>p</p>
  2531. </div>
  2532. );
  2533. };
  2534. export { SelectPosition };
  2535. SelectPosition.story = {
  2536. name: 'Select position problem'
  2537. }
  2538. const RenderOptionDemo = () => {
  2539. const optionList = [
  2540. { value: 'db-4', label: 'Doubao-Pro-4k', otherKey: 0, 'data-cy': 'option-1' },
  2541. { value: 'db-32', label: 'Doubao-Pro-32K', otherKey: 1, 'data-cy': 'option-2' },
  2542. { value: 'db-128', label: 'Doubao-Pro-128K', otherKey: 2, 'data-cy': 'option-3' },
  2543. { value: 'db-lite-2', label: 'Doubao-Lite-4K', otherKey: 4, 'data-cy': 'option-4' },
  2544. { value: 'db-lite-32', label: 'Doubao-Lite-32K', otherKey: 5, 'data-cy': 'option-5' },
  2545. { value: 'db-lite-128', label: 'Doubao-Lite-128K', otherKey: 6, 'data-cy': 'option-6' },
  2546. { value: 'gpt-4', label: 'GPT-4', otherKey: 6, 'data-cy': 'option-7' },
  2547. { value: 'gpt-4-32', label: 'GPT-4-32K', otherKey: 7, 'data-cy': 'option-8' },
  2548. ];
  2549. const renderOptionItem = renderProps => {
  2550. const {
  2551. disabled,
  2552. selected,
  2553. label,
  2554. value,
  2555. focused,
  2556. className,
  2557. style,
  2558. onMouseEnter,
  2559. onClick,
  2560. empty,
  2561. emptyContent,
  2562. ...rest
  2563. } = renderProps;
  2564. const optionCls = classNames({
  2565. ['custom-option-render']: true,
  2566. ['custom-option-render-focused']: focused,
  2567. ['custom-option-render-disabled']: disabled,
  2568. ['custom-option-render-selected']: selected,
  2569. }, className); // Notice:
  2570. // 1.props传入的style需在wrapper dom上进行消费,否则在虚拟化场景下会无法正常使用
  2571. // 2.选中(selected)、聚焦(focused)、禁用(disabled)等状态的样式需自行加上,你可以从props中获取到相对的boolean值
  2572. // 3.onMouseEnter需在wrapper dom上绑定,否则上下键盘操作时显示会有问题
  2573. // 4.props传入的className需在wrapper dom上绑定,否则上下键盘操作时可能存在无法自动滚动展示的问题
  2574. return (
  2575. <div
  2576. style={style}
  2577. className={optionCls}
  2578. onClick={() => onClick()}
  2579. onMouseEnter={e => onMouseEnter()}
  2580. {...rest}
  2581. >
  2582. <Checkbox checked={selected} />
  2583. <div className="option-right">{label}</div>
  2584. </div>
  2585. );
  2586. };
  2587. return (
  2588. <>
  2589. <Select
  2590. filter
  2591. dropdownClassName="components-select-demo-renderOptionItem"
  2592. optionList={optionList}
  2593. style={{
  2594. width: 300,
  2595. }}
  2596. data-cy="single"
  2597. maxHeight={180}
  2598. renderOptionItem={renderOptionItem}
  2599. />
  2600. <br />
  2601. <br />
  2602. <Select
  2603. filter
  2604. multiple
  2605. dropdownClassName="components-select-demo-renderOptionItem"
  2606. optionList={optionList}
  2607. maxHeight={180}
  2608. data-cy="multiple"
  2609. style={{
  2610. width: 450,
  2611. }}
  2612. renderOptionItem={renderOptionItem}
  2613. />
  2614. </>
  2615. );
  2616. };
  2617. export const RenderOptionItem = () => <RenderOptionDemo />;
  2618. RenderOptionItem.story = {
  2619. name: 'renderOptionItem',
  2620. };
  2621. const FilterDefaultOpen = () => {
  2622. const [value1, setValue1] = useState('a-1');
  2623. return (
  2624. <>
  2625. <Select
  2626. placeholder=""
  2627. style={{
  2628. width: 180,
  2629. }}
  2630. filter
  2631. defaultOpen
  2632. >
  2633. <Select.OptGroup label="Asia">
  2634. <Select.Option value="a-1">China</Select.Option>
  2635. <Select.Option value="a-2">Korea</Select.Option>
  2636. </Select.OptGroup>
  2637. <Select.OptGroup label="Europe">
  2638. <Select.Option value="b-1">Germany</Select.Option>
  2639. <Select.Option value="b-2">France</Select.Option>
  2640. </Select.OptGroup>
  2641. <Select.OptGroup label="South America">
  2642. <Select.Option value="c-1">Peru</Select.Option>
  2643. </Select.OptGroup>
  2644. </Select>
  2645. <Select
  2646. placeholder=""
  2647. style={{
  2648. width: 180,
  2649. marginLeft: 20,
  2650. }}
  2651. filter
  2652. defaultOpen
  2653. defaultValue="a-2"
  2654. >
  2655. <Select.OptGroup label="Asia">
  2656. <Select.Option value="a-1">China</Select.Option>
  2657. <Select.Option value="a-2">Korea</Select.Option>
  2658. </Select.OptGroup>
  2659. <Select.OptGroup label="Europe">
  2660. <Select.Option value="b-1">Germany</Select.Option>
  2661. <Select.Option value="b-2">France</Select.Option>
  2662. </Select.OptGroup>
  2663. <Select.OptGroup label="South America">
  2664. <Select.Option value="c-1">Peru</Select.Option>
  2665. </Select.OptGroup>
  2666. </Select>
  2667. <Select
  2668. placeholder=""
  2669. style={{
  2670. width: 180,
  2671. marginLeft: 20,
  2672. }}
  2673. filter
  2674. defaultOpen
  2675. value={value1}
  2676. onChange={val => setValue1(val)}
  2677. >
  2678. <Select.Option value="a-1">China</Select.Option>
  2679. <Select.Option value="a-2">Korea</Select.Option>
  2680. <Select.Option value="b-1">Germany</Select.Option>
  2681. <Select.Option value="b-2">France</Select.Option>
  2682. <Select.Option value="c-1">Peru</Select.Option>
  2683. </Select>
  2684. </>
  2685. );
  2686. };
  2687. export { FilterDefaultOpen };
  2688. FilterDefaultOpen.story = {
  2689. name: 'Filter + defaultOpen'
  2690. };
  2691. const CustomSelect = props => {
  2692. const { fieldRef, ...rest } = props;
  2693. return <Select {...rest} ref={fieldRef} />;
  2694. };
  2695. const CustomFieldSelect = withField(CustomSelect);
  2696. const RefDemo = () => {
  2697. const fieldRef = useRef(null);
  2698. const onChange = () => {
  2699. console.log(fieldRef);
  2700. fieldRef.current.open();
  2701. debugger;
  2702. };
  2703. return (
  2704. <Form>
  2705. <CustomFieldSelect field="test" initValue="se" fieldRef={fieldRef}></CustomFieldSelect>
  2706. <Button onClick={onChange}>change</Button>
  2707. </Form>
  2708. );
  2709. };
  2710. export const RefFieldDemo = () => <RefDemo />;
  2711. RefFieldDemo.story = {
  2712. name: 'Ref field demo',
  2713. };
  2714. const ValueZeroDemo = () => {
  2715. const list = [
  2716. {
  2717. value: 6,
  2718. label: '抖音小视频',
  2719. otherKey: 0,
  2720. },
  2721. {
  2722. value: 1,
  2723. label: '火山小视频',
  2724. disabled: true,
  2725. otherKey: 1,
  2726. },
  2727. {
  2728. value: 'pipixia',
  2729. label: '皮皮虾',
  2730. otherKey: 2,
  2731. },
  2732. {
  2733. value: 'toutiao',
  2734. label: '今日头条',
  2735. otherKey: 3,
  2736. },
  2737. ];
  2738. return (
  2739. <Select
  2740. placeholder="请选择业务线"
  2741. style={{
  2742. width: 180,
  2743. }}
  2744. optionList={list}
  2745. value={0}
  2746. renderSelectedItem={option => option.label + 1}
  2747. ></Select>
  2748. );
  2749. };
  2750. export const Value0 = () => <ValueZeroDemo />;
  2751. Value0.story = {
  2752. name: 'value=0',
  2753. };
  2754. export const ScrollIntoView = () => (
  2755. <div>
  2756. <p>single selection</p>
  2757. <Select defaultValue='v-11' defaultOpen style={{ width: 120, marginBottom: 300 }}>
  2758. {new Array(50).fill(null).map((item, idx) => (
  2759. <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
  2760. ))}
  2761. </Select>
  2762. <p>single selection with no selected item</p>
  2763. <Select style={{ marginBottom: 300, width: 120 }}>
  2764. {new Array(50).fill(null).map((item, idx) => (
  2765. <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
  2766. ))}
  2767. </Select>
  2768. <p>The selected node is the last</p>
  2769. <Select defaultValue='v-49' defaultOpen style={{ marginBottom: 300, width: 120 }}>
  2770. {new Array(50).fill(null).map((item, idx) => (
  2771. <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
  2772. ))}
  2773. </Select>
  2774. <p>The selected node is the first</p>
  2775. <Select defaultValue='v-0' style={{ marginBottom: 300, width: 120 }}>
  2776. {new Array(50).fill(null).map((item, idx) => (
  2777. <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
  2778. ))}
  2779. </Select>
  2780. <p>multiple selection</p>
  2781. <Select defaultValue={['v-25', 'v-9']} multiple style={{ marginBottom: 300, width: 220 }}>
  2782. {new Array(30).fill(null).map((item, idx) => (
  2783. <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
  2784. ))}
  2785. </Select>
  2786. <p>multiple selection with no selected item</p>
  2787. <Select multiple style={{ marginBottom: 300, width: 220 }}>
  2788. {new Array(30).fill(null).map((item, idx) => (
  2789. <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
  2790. ))}
  2791. </Select>
  2792. </div>
  2793. );
  2794. ScrollIntoView.story = {
  2795. name: 'scroll into view',
  2796. };
  2797. export const SelectInputPropsDemo = () => {
  2798. const inputProps = {
  2799. className: 'ttt',
  2800. onCompositionEnd: (v) => console.log(v.target.value)
  2801. };
  2802. return (
  2803. <Select
  2804. // onSearch={(v) => console.log(v)}
  2805. optionList={list}
  2806. inputProps={inputProps}
  2807. multiple
  2808. filter
  2809. style={{ width: 200 }}
  2810. >
  2811. </Select>
  2812. )
  2813. };
  2814. SelectInputPropsDemo.story = {
  2815. name: 'inputProps',
  2816. };
  2817. export const AutoClearSearchValue = () => {
  2818. const [val, setVal] = useState(['semi1']);
  2819. const [clear, setClear] = useState(false);
  2820. const optionList = [
  2821. { label: 'semi1', value: 'semi1' },
  2822. { label: 'semi2', value: 'semi2' },
  2823. { label: 'semi3', value: 'semi3' },
  2824. { label: 'semi4', value: 'semi4' },
  2825. { label: 'semi5', value: 'semi5' },
  2826. { label: 'semi6', value: 'semi6' },
  2827. ];
  2828. const [loading, setLoading] = useState(false);
  2829. const [list, setList] = useState(optionList);
  2830. const [value, setValue] = useState('');
  2831. const handleChange = newValue => { setValue(newValue); };
  2832. const data2 = [
  2833. {
  2834. label: "Design",
  2835. value: '123456',
  2836. }
  2837. ]
  2838. const handleSearch = (inputValue) => {
  2839. setLoading(true);
  2840. if (inputValue) {
  2841. setTimeout(() => {
  2842. setLoading(false);
  2843. setList(data2);
  2844. }, 1000);
  2845. } else {
  2846. setList(optionList)
  2847. setLoading(false);
  2848. }
  2849. };
  2850. return (
  2851. <>
  2852. <h4>autoClearSearchValue</h4>
  2853. <Switch checked={clear} onChange={checked => setClear(checked)}></Switch>
  2854. <h4>Controlled mode + multiple</h4>
  2855. <Select style={{ width: 400 }} multiple optionList={optionList} filter value={val} onChange={value => setVal(value)} autoClearSearchValue={clear}></Select>
  2856. <br />
  2857. <br />
  2858. <h4>Uncontrolled mode + multiple</h4>
  2859. <Select style={{ width: 400 }} multiple optionList={optionList} filter autoClearSearchValue={clear}></Select>
  2860. <h4>Uncontrolled mode + multiple + defaultValue</h4>
  2861. <Select style={{ width: 400 }} multiple optionList={optionList} filter defaultValue={['semi2']} autoClearSearchValue={clear}></Select>
  2862. <h4>controlled mode + update optionList + remote + autoClearSearchValue = false</h4>
  2863. <Select
  2864. style={{ width: 400 }}
  2865. multiple
  2866. optionList={list}
  2867. filter
  2868. remote
  2869. className='remote-select'
  2870. loading={loading}
  2871. value={value}
  2872. onChange={handleChange}
  2873. autoClearSearchValue={clear}
  2874. onSearch={handleSearch}
  2875. >
  2876. </Select>
  2877. </>
  2878. )
  2879. }
  2880. AutoClearSearchValue.story = {
  2881. name: 'AutoClearSearchValue',
  2882. };
  2883. export const RenderSelectedItemCallCount = () => {
  2884. const list = [
  2885. { "name": "夏可漫", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg" },
  2886. { "name": "申悦", "email": "[email protected]", "avatar": "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg" },
  2887. { "name": "曲晨一", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg" },
  2888. { "name": "文嘉茂", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png" },
  2889. { "name": "文嘉茂2", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png" },
  2890. { "name": "文嘉茂3", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png" },
  2891. ]
  2892. const renderMultipleWithCustomTag = (optionNode, { onClose }) => {
  2893. console.count('rerender')
  2894. const content = (
  2895. <Tag
  2896. avatarSrc={optionNode.avatar}
  2897. avatarShape='circle'
  2898. closable={true}
  2899. onClose={onClose}
  2900. size='large'
  2901. >
  2902. {optionNode.name}
  2903. </Tag>
  2904. );
  2905. return {
  2906. isRenderInTag: false,
  2907. content
  2908. };
  2909. }
  2910. const renderCustomOption = (item, index) => {
  2911. const optionStyle = {
  2912. display: 'flex',
  2913. paddingLeft: 24,
  2914. paddingTop: 10,
  2915. paddingBottom: 10
  2916. }
  2917. return (
  2918. <Select.Option value={item.name} style={optionStyle} showTick={true} {...item} key={item.email}>
  2919. <Avatar size="small" src={item.avatar} />
  2920. <div style={{ marginLeft: 8 }}>
  2921. <div style={{ fontSize: 14 }}>{item.name}</div>
  2922. <div style={{ color: 'var(--color-text-2)', fontSize: 12, lineHeight: '16px', fontWeight: 'normal' }}>{item.email}</div>
  2923. </div>
  2924. </Select.Option>
  2925. )
  2926. }
  2927. return (
  2928. <>
  2929. <Select
  2930. placeholder='请选择'
  2931. showClear
  2932. multiple
  2933. maxTagCount={2}
  2934. style={{ width: 280, height: 40 }}
  2935. onChange={v => console.log(v)}
  2936. defaultValue={'夏可漫'}
  2937. renderSelectedItem={renderMultipleWithCustomTag}
  2938. >
  2939. {list.map((item, index) => renderCustomOption(item, index))}
  2940. </Select>
  2941. </>
  2942. );
  2943. }
  2944. RenderSelectedItemCallCount.story = {
  2945. name: 'RenderSelectedItemCallCount',
  2946. };
  2947. const RenderSelectedItemWithMaxTagCount = () => {
  2948. const list = [
  2949. { "name": "夏可漫", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg" },
  2950. { "name": "申悦", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg" },
  2951. { "name": "曲晨一", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg" },
  2952. { "name": "文嘉茂", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/6fbafc2d-e3e6-4cff-a1e2-17709c680624.png" },
  2953. ];
  2954. const renderMultipleWithCustomTag = (optionNode, { onClose }) => {
  2955. const content = (
  2956. <Tag
  2957. avatarSrc={optionNode.avatar}
  2958. avatarShape='circle'
  2959. closable={true}
  2960. onClose={onClose}
  2961. size='large'
  2962. style={{ maxWidth: '100%'}}
  2963. >
  2964. {optionNode.email}
  2965. </Tag>
  2966. );
  2967. return {
  2968. isRenderInTag: false,
  2969. content
  2970. };
  2971. };
  2972. const renderMultipleWithCustomTag2 = (optionNode, { onClose }) => {
  2973. const content = (
  2974. <Tag
  2975. avatarSrc={optionNode.avatar}
  2976. avatarShape='square'
  2977. closable={true}
  2978. onClose={onClose}
  2979. size='large'
  2980. style={{ maxWidth: '100%'}}
  2981. >
  2982. {optionNode.name}
  2983. </Tag>
  2984. );
  2985. return {
  2986. isRenderInTag: false,
  2987. content
  2988. };
  2989. };
  2990. const renderCustomOption = (item, index) => {
  2991. const optionStyle = {
  2992. display: 'flex',
  2993. paddingLeft: 24,
  2994. paddingTop: 10,
  2995. paddingBottom: 10
  2996. };
  2997. return (
  2998. <Select.Option value={item.name} style={optionStyle} showTick={true} {...item} key={item.email}>
  2999. <Avatar size="small" src={item.avatar} />
  3000. <div style={{ marginLeft: 8 }}>
  3001. <div style={{ fontSize: 14 }}>{item.email}</div>
  3002. <div style={{ color: 'var(--color-text-2)', fontSize: 12, lineHeight: '16px', fontWeight: 'normal' }}>{item.email}</div>
  3003. </div>
  3004. </Select.Option>
  3005. );
  3006. };
  3007. return (
  3008. <>
  3009. renderSelectedItem + maxTagCount=10 + defaultValue.length=2
  3010. <br />
  3011. <Select
  3012. placeholder='请选择'
  3013. maxTagCount={10}
  3014. style={{ width: 350, marginTop: 20 }}
  3015. onChange={v => console.log(v)}
  3016. defaultValue={['夏可漫', '申悦']}
  3017. multiple
  3018. renderSelectedItem={renderMultipleWithCustomTag}
  3019. ellipsisTrigger
  3020. showRestTagsPopover
  3021. expandRestTagsOnClick
  3022. >
  3023. {list.map((item, index) => renderCustomOption(item, index))}
  3024. </Select>
  3025. <br />
  3026. <br />
  3027. renderSelectedItem + maxTagCount=1 + defaultValue.length=2 + filter
  3028. <br />
  3029. <Select
  3030. placeholder='请选择'
  3031. maxTagCount={1}
  3032. filter
  3033. style={{ width: 350, marginTop: 20 }}
  3034. onChange={v => console.log(v)}
  3035. defaultValue={['夏可漫', '申悦']}
  3036. multiple
  3037. renderSelectedItem={renderMultipleWithCustomTag2}
  3038. ellipsisTrigger
  3039. showRestTagsPopover
  3040. expandRestTagsOnClick
  3041. >
  3042. {list.map((item, index) => renderCustomOption(item, index))}
  3043. </Select>
  3044. </>
  3045. );
  3046. };
  3047. export const NPlusTruncationStrategy = () => {
  3048. const shortVal = ['semi11', 'semi1']
  3049. const val = ['semi11', 'semi1', 'semi3', 'semi4', 'semi10']
  3050. const allSelect = ['semi11', 'semi1', 'semi2', 'semi3', 'semi4', 'semi5', 'semi6', 'semi7', 'semi8', 'semi9', 'semi10']
  3051. const options = [
  3052. { label: 'semi1semi1', value: 'semi1' },
  3053. { label: 'semi2semi2semi2', value: 'semi2' },
  3054. { label: 'semi3semi3semi3semi3', value: 'semi3' },
  3055. { label: 'semi4semi4semi4semi4semi4', value: 'semi4' },
  3056. { label: 'semi5semi5semi5semi5semi5semi5', value: 'semi5' },
  3057. { label: 'semi6semi6semi6semi6semi6semi6semi6', value: 'semi6' },
  3058. { label: 'semi7semi7semi7semi7semi7semi7semi7', value: 'semi7' },
  3059. { label: 'semi8semi8semi8semi8semi8semi8semi8', value: 'semi8' },
  3060. { label: 'semi9semi9semi9semi9semi9semi9semi9', value: 'semi9' },
  3061. { label: 'semi10semi10semi10semi10semi10semi10', value: 'semi10' },
  3062. { label: '我是中文超长选项我真的真的真的真的真的真的超级长', value: 'semi11' },
  3063. ];
  3064. // expandRestTagsOnClick
  3065. return (
  3066. <>
  3067. <h4>未设置宽度 和 maxTagCount </h4>
  3068. defaultValue.length = 5
  3069. <br /><br />
  3070. <Select multiple optionList={options} defaultValue={val} ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3071. <br /><br /><br />
  3072. <h4>未设置宽度</h4>
  3073. maxTagCount = 2 + defaultValue.length = 5
  3074. <br /><br />
  3075. <Select maxTagCount={2} multiple optionList={options} defaultValue={val} ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3076. <br /><br />
  3077. maxTagCount = 2 + defaultValue.length = 5 + expandRestTagsOnClick=false
  3078. <br /><br />
  3079. <Select maxTagCount={2} multiple optionList={options} defaultValue={val} expandRestTagsOnClick={false} ellipsisTrigger showRestTagsPopover></Select>
  3080. <br /><br />
  3081. maxTagCount = 6 + defaultValue.length = 5
  3082. <br /><br />
  3083. <Select maxTagCount={6} multiple optionList={options} defaultValue={val} ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3084. <br /><br />
  3085. maxTagCount = 6 + defaultValue.length = 5 + filter
  3086. <br /><br />
  3087. <Select maxTagCount={6} multiple optionList={options} defaultValue={val} filter ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3088. <br /><br /><br />
  3089. <h4>定宽</h4>
  3090. maxTagCount = 2 + defaultValue.length = 2
  3091. <br /><br />
  3092. <Select style={{ width: '350px' }} maxTagCount={2} multiple optionList={options} defaultValue={shortVal} showClear ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3093. <br /><br />
  3094. maxTagCount = 5 + defaultValue.length = 5
  3095. <br /><br />
  3096. <Select style={{ width: '550px' }} maxTagCount={5} multiple optionList={options} defaultValue={val} showClear ellipsisTrigger showRestTagsPopove expandRestTagsOnClick></Select>
  3097. <br /><br />
  3098. maxTagCount = 10 + defaultValue.length = 11
  3099. <br /><br />
  3100. <Select style={{ width: '550px' }} maxTagCount={10} multiple optionList={options} defaultValue={allSelect} showClear ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3101. <br /><br />
  3102. maxTagCount = 10 + defaultValue.length = 11 + filter
  3103. <br /><br />
  3104. <Select style={{ width: '550px' }} maxTagCount={10} multiple optionList={options} defaultValue={allSelect} filter showClear ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3105. <br /><br />
  3106. maxTagCount = 10 + defaultValue.length = 11 + expandRestTagsOnClick=false
  3107. <br /><br />
  3108. <Select style={{ width: '550px' }} maxTagCount={10} multiple optionList={options} defaultValue={allSelect} expandRestTagsOnClick={false} showClear ellipsisTrigger showRestTagsPopover></Select>
  3109. <br /><br /><br />
  3110. <h4>能保证正常渲染的最小宽度至少是120px</h4>
  3111. <Select style={{ width: '120px' }} maxTagCount={10} multiple optionList={options} defaultValue={val} showClear ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3112. <br /><br /><br />
  3113. <h4>前缀/后缀/insetLabel</h4>
  3114. maxTagCount = 2 + defaultValue.length = 2 + prefix
  3115. <br /><br />
  3116. <Select style={{ width: '500px' }} maxTagCount={2} prefix={<IconSearch />} multiple optionList={options} defaultValue={shortVal} ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3117. <br /><br />
  3118. maxTagCount = 6 + defaultValue.length = 5 + suffix
  3119. <br /><br />
  3120. <Select style={{ width: '500px' }} maxTagCount={6} suffix={<IconSearch />} multiple optionList={options} defaultValue={val} ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3121. <br /><br />
  3122. maxTagCount = 6 + defaultValue.length = 11 + insetLabel
  3123. <br /><br />
  3124. <Select style={{ width: '500px' }} maxTagCount={6} insetLabel={<IconSearch />} multiple optionList={options} defaultValue={allSelect} ellipsisTrigger showRestTagsPopover expandRestTagsOnClick></Select>
  3125. <br /><br /><br />
  3126. <h4>renderSelectedItem</h4>
  3127. <RenderSelectedItemWithMaxTagCount />
  3128. <br />
  3129. </>
  3130. )
  3131. }
  3132. NPlusTruncationStrategy.story = {
  3133. name: 'NPlusTruncationStrategy',
  3134. };
  3135. export const emptyContent = () => {
  3136. const list = null;
  3137. return (
  3138. <Select placeholder='请选择业务线' emptyContent={null} style={{ width: 180 }} optionList={list} defaultOpen={true}/>
  3139. )
  3140. }
  3141. export const Fix1584 = () => {
  3142. return (
  3143. <>
  3144. defaultValue is null
  3145. <br />
  3146. <Select
  3147. style={{ width: 180 }}
  3148. defaultValue={null}
  3149. placeholder="带搜索功能的单选"
  3150. renderSelectedItem={(item) => {
  3151. console.log('items', item);
  3152. return <div>{item.label}</div>}}
  3153. >
  3154. <Select.Option value="abc">抖音</Select.Option>
  3155. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3156. <Select.Option value="jianying">剪映</Select.Option>
  3157. <Select.Option value="xigua">西瓜视频</Select.Option>
  3158. </Select>
  3159. <br />
  3160. <br />
  3161. defaultValue is undefined
  3162. <br />
  3163. <Select
  3164. style={{ width: 180 }}
  3165. defaultValue={undefined}
  3166. placeholder="带搜索功能的单选"
  3167. renderSelectedItem={(item) => <div>{item.label}</div>}
  3168. >
  3169. <Select.Option value="abc">抖音</Select.Option>
  3170. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3171. <Select.Option value="jianying">剪映</Select.Option>
  3172. <Select.Option value="xigua">西瓜视频</Select.Option>
  3173. </Select>
  3174. </>
  3175. );
  3176. }
  3177. export const Fix1560 = () => {
  3178. return (
  3179. <div>
  3180. <h4>边界 case 测试</h4>
  3181. <h4>maxTagCount = 3,截断最后一个 tag, 加减项正常</h4>
  3182. <Select
  3183. multiple
  3184. maxTagCount={3}
  3185. ellipsisTrigger
  3186. showRestTagsPopover={true}
  3187. restTagsPopoverProps={{ position: 'top' }}
  3188. style={{ width: '255px' }}
  3189. defaultValue={['abc', 'ulikecam', "xigua"]}
  3190. >
  3191. <Select.Option value="abc">抖音</Select.Option>
  3192. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3193. <Select.Option value="jianying">剪映</Select.Option>
  3194. <Select.Option value="xigua">西瓜视频</Select.Option>
  3195. </Select>
  3196. <br /><br />
  3197. <h4>maxTagCount = 3,最大宽度只展示 2 个 Tag,加减项正常</h4>
  3198. <Select
  3199. multiple
  3200. maxTagCount={2}
  3201. ellipsisTrigger
  3202. showRestTagsPopover={true}
  3203. restTagsPopoverProps={{ position: 'top' }}
  3204. style={{ width: '240px' }}
  3205. defaultValue={['xigua', 'ulikecam', 'jianying', 'abc']}
  3206. >
  3207. <Select.Option value="abc">抖音</Select.Option>
  3208. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3209. <Select.Option value="jianying">剪映</Select.Option>
  3210. <Select.Option value="xigua">西瓜视频</Select.Option>
  3211. </Select>
  3212. </div>
  3213. );
  3214. }
  3215. class VirtualizeAllowCreate extends React.Component {
  3216. constructor(props) {
  3217. super(props);
  3218. const taskList=[{
  3219. "task_id": 500333,
  3220. "task_name": "抖音直播间-哈哈哈",
  3221. "task_key": "hhh_watch_live"
  3222. },]
  3223. let newOptions = taskList.map(r=>({value:r.task_id,label:`${r.task_id} ${r.task_name}`}))
  3224. this.state = {
  3225. optionList: newOptions,
  3226. };
  3227. }
  3228. render() {
  3229. let { optionList } = this.state;
  3230. let virtualize = {
  3231. height: 270,
  3232. width: '100%',
  3233. itemSize: 36, // px
  3234. };
  3235. return (
  3236. <>
  3237. <Select
  3238. allowCreate
  3239. placeholder="拥有3k个Option的Select"
  3240. style={{ width: 260 }}
  3241. filter
  3242. onSearch={this.handleSearch}
  3243. virtualize={virtualize}
  3244. optionList={optionList}
  3245. renderCreateItem={(iv, isFocused, style) => <div style={{ padding: '6px 12px', ...style }}>输入 {iv}</div>}
  3246. ></Select>
  3247. </>
  3248. );
  3249. }
  3250. }
  3251. // virtualize allowCreate + renderCreateItem, optionList render not as expected
  3252. export const Fix1856 = () => (<VirtualizeAllowCreate />);
  3253. export const TestOptionKey = () => {
  3254. return <><Select style={{ width: 300 }}>
  3255. <Select.Option label='abc' value='2' key='abc'></Select.Option>
  3256. <Select.Option label='efg' value='3' key='efg'></Select.Option>
  3257. <Select.Option label='kkk' value='5'></Select.Option>
  3258. <Select.Option label='fff' value='4'></Select.Option>
  3259. </Select>
  3260. <br/><br/>
  3261. <Select style={{ width: 300 }} optionList={[
  3262. { label: '1', value: '2', key: 'kkk' },
  3263. { label: '2', value: '3', key: 'jjj' },
  3264. { label: '3', value: '2' },
  3265. ]}>
  3266. </Select>
  3267. </>
  3268. }
  3269. export const AllCaseOfBlur = () => {
  3270. const BaseSelect = (props) => {
  3271. return (
  3272. <Select defaultValue="abc" style={{ width: 120 }} {...props} >
  3273. <Select.Option value="abc">抖音</Select.Option>
  3274. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3275. <Select.Option value="jianying" disabled>
  3276. 剪映
  3277. </Select.Option>
  3278. <Select.Option value="xigua">西瓜视频</Select.Option>
  3279. </Select>
  3280. )
  3281. }
  3282. return (
  3283. <div>
  3284. <h3>单选</h3>
  3285. <Divider margin='12px' />
  3286. <h5>默认配置</h5>
  3287. <BaseSelect data-cy="singleDefault" onBlur={()=>{console.log('single default onBlur')}} />
  3288. <br />
  3289. <h5>filter</h5>
  3290. <BaseSelect data-cy="singleFilter" filter onBlur={()=>{console.log('single filter onBlur')}} />
  3291. <br />
  3292. <h5>autoFocus</h5>
  3293. <BaseSelect data-cy="singleAutoFocus" autoFocus onBlur={()=>{console.log('single autoFocus onBlur')}} />
  3294. <br />
  3295. <h5>clickToHide</h5>
  3296. <BaseSelect data-cy="singleClickToHide" clickToHide onBlur={()=>{console.log('single clickToHide onBlur')}} />
  3297. <br />
  3298. <h5>showClear</h5>
  3299. <BaseSelect data-cy="singleShowClear" showClear onBlur={()=>{console.log('single showClear onBlur')}} />
  3300. <h3>多选</h3>
  3301. <Divider margin='12px' />
  3302. <h5>默认配置</h5>
  3303. <BaseSelect data-cy="multipleDefault" multiple onBlur={()=>{console.log('multiple default onBlur')}} />
  3304. <br />
  3305. <h5>filter</h5>
  3306. <BaseSelect data-cy="multipleFilter" multiple filter onBlur={()=>{console.log('multiple filter onBlur')}} />
  3307. <h5>clickToHide</h5>
  3308. <BaseSelect data-cy="multipleClickToHide" multiple clickToHide onBlur={()=>{console.log('multiple clickToHide onBlur')}} />
  3309. <h5>showClear</h5>
  3310. <BaseSelect data-cy="multipleShowClear" multiple showClear onBlur={()=>{console.log('multiple showClear onBlur')}} />
  3311. <br />
  3312. <br />
  3313. </div>
  3314. )
  3315. }
  3316. export const UpdateOtherKeyNotInList = () => {
  3317. const [v, setV] = useState([
  3318. {
  3319. label: 'AA-Label',
  3320. value: 'AA',
  3321. otherProps: 'AA-OtherProps',
  3322. },
  3323. ]);
  3324. const change = () => {
  3325. setV([
  3326. {
  3327. label: 'AA-Label-2',
  3328. value: 'AA',
  3329. otherProps: 'AA-OtherProps-2',
  3330. },
  3331. ])
  3332. }
  3333. const renderSelectedItem = (optionNode) => {
  3334. const { label, otherProps } = optionNode;
  3335. const content = (
  3336. <div className='render-content'>
  3337. {label}-{otherProps}
  3338. </div>
  3339. );
  3340. return {
  3341. isRenderInTag: false,
  3342. content,
  3343. };
  3344. };
  3345. return (
  3346. <>
  3347. <Select
  3348. value={v}
  3349. onChange={setV}
  3350. filter
  3351. multiple
  3352. renderSelectedItem={renderSelectedItem}
  3353. onChangeWithObject
  3354. style={{ width: 320 }}
  3355. />
  3356. <Button id='change' onClick={() => change()}>change</Button>
  3357. </>
  3358. );
  3359. };
  3360. export const ControledSameLabelInNode = () => {
  3361. const [value, setValue] = useState();
  3362. return <Select style={{ width: 180 }}
  3363. value={value}
  3364. id='test'
  3365. // motion={false}
  3366. data-cy="singleControl"
  3367. onChange={(value) => {
  3368. console.log('change');
  3369. console.log(value)
  3370. setValue(value)
  3371. }}>
  3372. <Select.OptGroup label="Asia">
  3373. <Select.Option value="a-1" label={<div>China</div>} className='a-1' data-cy='a-1' key={'a-1'}></Select.Option>
  3374. <Select.Option value="a-2" label={<div>China</div>} className='a-2' data-cy='a-2' key={'a-2'}></Select.Option>
  3375. <Select.Option value="a-3" label={<div>Korea</div>} className='a-3'></Select.Option>
  3376. </Select.OptGroup>
  3377. <Select.OptGroup label="Europe">
  3378. <Select.Option value="b-1" label={<div>Germany</div>}></Select.Option>
  3379. <Select.Option value="b-2" label={<div>France</div>}></Select.Option>
  3380. </Select.OptGroup>
  3381. </Select>
  3382. }
  3383. export const SearchPosition = () => {
  3384. return (<>
  3385. <Select
  3386. filter
  3387. searchPosition='dropdown'
  3388. onChangeWithObject
  3389. placeholder={'single searchPosition=dropdown'}
  3390. optionList={optionList}
  3391. searchPlaceholder='dropdown input place'
  3392. showClear
  3393. autoFocus
  3394. style={{ width: 320 }}
  3395. />
  3396. <Select
  3397. filter
  3398. multiple
  3399. placeholder={'multiple searchPosition=dropdown'}
  3400. searchPosition='dropdown'
  3401. onChangeWithObject
  3402. showClear
  3403. searchPlaceholder='dropdown input place'
  3404. autoClearSearchValue={false}
  3405. optionList={optionList}
  3406. style={{ width: 320 }}
  3407. />
  3408. </>
  3409. )
  3410. }
  3411. export const fix2465 = () => {
  3412. let singleSelectBox = useRef(null);
  3413. let multipleSelectBox = useRef(null);
  3414. let outSlotStyle = {
  3415. backgroundColor: 'var(--semi-color-fill-0)',
  3416. height: '36px',
  3417. display: 'flex',
  3418. paddingLeft: 32,
  3419. color: 'var(--semi-color-link)',
  3420. alignItems: 'center',
  3421. cursor: 'pointer',
  3422. borderTop: '1px solid var(--semi-color-border)',
  3423. borderRadius: '0 0 6px 6px',
  3424. };
  3425. let singleOutSlotNode = (
  3426. <div style={outSlotStyle}>
  3427. <button onClick={(e)=>{singleSelectBox.current.close()}}>single close</button>
  3428. </div>
  3429. );
  3430. let multipleOutSlotNode = (
  3431. <div style={outSlotStyle}>
  3432. <button onClick={(e)=>{multipleSelectBox.current.close()}}>multiple close</button>
  3433. </div>
  3434. );
  3435. return (
  3436. <div>
  3437. <p>点击 Select 展开弹层后,点击 close 按钮关闭弹层,最后点击外部,检查 Select 聚焦样式是否消失 </p>
  3438. <Select
  3439. ref={singleSelectBox}
  3440. style={{ width: 300 }}
  3441. dropdownStyle={{ width: 180 }}
  3442. maxHeight={150}
  3443. outerBottomSlot={singleOutSlotNode}
  3444. placeholder="单选"
  3445. autoAdjustOverflow={false}
  3446. position="bottom"
  3447. >
  3448. <Select.Option value="abc">抖音</Select.Option>
  3449. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3450. <Select.Option value="jianying">剪映</Select.Option>
  3451. <Select.Option value="duoshan">多闪</Select.Option>
  3452. <Select.Option value="xigua">西瓜视频</Select.Option>
  3453. </Select>
  3454. <br />
  3455. <br />
  3456. <Select
  3457. ref={multipleSelectBox}
  3458. style={{ width: 300 }}
  3459. dropdownStyle={{ width: 180 }}
  3460. maxHeight={150}
  3461. outerBottomSlot={multipleOutSlotNode}
  3462. placeholder="多选"
  3463. autoAdjustOverflow={false}
  3464. multiple
  3465. position="bottom"
  3466. >
  3467. <Select.Option value="abc">抖音</Select.Option>
  3468. <Select.Option value="ulikecam">轻颜相机</Select.Option>
  3469. <Select.Option value="jianying">剪映</Select.Option>
  3470. <Select.Option value="duoshan">多闪</Select.Option>
  3471. <Select.Option value="xigua">西瓜视频</Select.Option>
  3472. </Select>
  3473. <Button onClick={()=>{multipleSelectBox.current.close()}}>close</Button>
  3474. </div>
  3475. );
  3476. }
  3477. export const Fix2853 = () => {
  3478. return (
  3479. <Select placeholder="" style={{ width: 180 }} filter>
  3480. <Select.OptGroup key="a" label={<div>a</div>} >
  3481. <Select.Option value="a-1" key="a-1">a-1</Select.Option>
  3482. <Select.Option value="a-2" key="a-2">a-2</Select.Option>
  3483. </Select.OptGroup>
  3484. <Select.OptGroup label={<div>b</div>} >
  3485. <Select.Option value="b-1">b-1</Select.Option>
  3486. <Select.Option value="b-2">b-2</Select.Option>
  3487. </Select.OptGroup>
  3488. <Select.OptGroup label={<div>c</div>} >
  3489. <Select.Option value="c-1">c-1</Select.Option>
  3490. </Select.OptGroup>
  3491. </Select>
  3492. )
  3493. }