123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988 |
- import React, { useState, useRef, useEffect } from 'react';
- import './select.scss';
- import { Input, Select, Button, Icon, Avatar, Checkbox, Form, withField, Space, Tag } from '../../index';
- import CustomTrigger from './CustomTrigger';
- import classNames from 'classnames';
- import { getHighLightTextHTML } from '../../_utils/index';
- const Option = Select.Option;
- import { IconSearch, IconGift } from '@douyinfe/semi-icons';
- export default {
- title: 'Select',
- parameters: {
- chromatic: { disableSnapshot: true },
- },
- }
- let Test = () => {
- let [options, setOptions] = useState([1, 2, 3, 4]);
- function add() {
- let newOptions = Array.from(
- {
- length: Math.floor(Math.random() * 10),
- },
- (v, i) => i + 1
- );
- setOptions(newOptions);
- }
- let style = {
- width: 150,
- margin: 20,
- };
- let slotStyle = {
- backgroundColor: 'whitesmoke',
- height: '40px',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- borderRadius: '0 0 6px 6px',
- };
- let outSlotStyle = {
- backgroundColor: 'whitesmoke',
- height: '29px',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- cursor: 'pointer',
- };
- const click = e => {};
- let outSlotNode = (
- <div onClick={e => click(e)}>
- <Checkbox>sendLarkNotification</Checkbox>
- <div>
- <Button theme="solid">confirm</Button>
- </div>
- </div>
- );
- return (
- <>
- <Select
- style={style}
- dropdownClassName="test-dropdown"
- dropdownStyle={{
- width: 150,
- }}
- filter
- placeholder="fefe"
- position="rightTop"
- innerBottomSlot={
- <div style={slotStyle}>
- <Button
- size="small"
- style={{
- margin: 0,
- }}
- >
- 申请其他地区权限
- </Button>
- </div>
- }
- >
- {options.map(option => (
- <Option value={option} key={option} className="fefe">
- {option}
- </Option>
- ))}
- </Select>
- <Select
- style={{
- marginTop: 20,
- width: 200,
- }}
- dropdownClassName="test-dropdown"
- dropdownStyle={{
- width: 150,
- }}
- filter
- placeholder="fefe"
- position="rightTop"
- outerBottomSlot={outSlotNode}
- >
- {options.map(option => (
- <Option value={option} key={option} className="fefe">
- {option}
- </Option>
- ))}
- </Select>
- </>
- );
- };
- const AutoFocusDemo = () => {
- return (
- <>
- <Select
- autoFocus
- style={{
- width: 200,
- }}
- onFocus={() => console.log('onFocus')}
- onBlur={() => console.log('onBlur')}
- >
- <Option value="abc">抖音</Option>
- <Option value="hotsoon">火山</Option>
- <Option value="pipixia">皮皮虾</Option>
- <Option value="duoshan">多闪</Option>
- <Option value="xigua">西瓜视频</Option>
- </Select>
- <div className="test-div">test-div</div>
- </>
- );
- };
- export const AutoFocus = () => <AutoFocusDemo />;
- AutoFocus.story = {
- name: 'autoFocus',
- };
- export const InnerBottomSlotOuterBottomSlot = () => <Test />;
- InnerBottomSlotOuterBottomSlot.story = {
- name: 'innerBottomSlot / outerBottomSlot',
- };
- export const InnerTopSlotOuterTopSlot = () => {
- const slot = <div>未找到应用?</div>;
- return (
- <div>
- innerTopSlot
- <div>
- <Select
- innerTopSlot={slot}
- style={{
- width: 250,
- }}
- maxHeight={150}
- >
- <Option value="abc">抖音</Option>
- <Option value="hotsoon">火山</Option>
- <Option value="pipixia">皮皮虾</Option>
- <Option value="duoshan">多闪</Option>
- <Option value="xigua">西瓜视频</Option>
- </Select>
- </div>
- outerTopSlot
- <div>
- <Select
- outerTopSlot={slot}
- style={{
- width: 250,
- }}
- maxHeight={150}
- >
- <Option value="abc">抖音</Option>
- <Option value="hotsoon">火山</Option>
- <Option value="pipixia">皮皮虾</Option>
- <Option value="duoshan">多闪</Option>
- <Option value="xigua">西瓜视频</Option>
- </Select>
- </div>
- </div>
- );
- };
- InnerTopSlotOuterTopSlot.story = {
- name: 'innerTopSlot / outerTopSlot',
- };
- export const OneOptionJsxWithOtherOptionArray = () => (
- <Select
- defaultValue={'all'}
- style={{
- width: 250,
- }}
- >
- <Option value="all" key="all">
- all
- </Option>
- {[1, 2, 3].map(item => (
- <Option value={`type${item}`} key={item}>{`type${item}`}</Option>
- ))}
- </Select>
- );
- OneOptionJsxWithOtherOptionArray.story = {
- name: 'one option jsx with other option array',
- };
- let options = [
- {
- value: 'all',
- label: '全部',
- otherKey: 'all semi',
- },
- {
- value: 'abc',
- label: '抖音',
- otherKey: 'abc semi',
- },
- {
- value: 'hotsoon',
- label: '火山小视频',
- otherKey: 'hostsoom semi',
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- otherKey: 'pif',
- },
- {
- value: 'toutiao',
- label: '今日头条',
- otherKey: 'toutiao semi',
- },
- {
- value: 'rd',
- label: 'rd',
- otherKey: 'semi rd',
- },
- {
- value: 'ued',
- label: 'ued',
- otherKey: 'semi ued',
- },
- {
- value: 'ued',
- label: 'japan',
- otherKey: 'semi ued',
- },
- {
- value: '+86',
- label: '+86',
- otherKey: 'semi',
- },
- ];
- let longOptions = options.concat({
- value: 'long',
- label: 'Semi Design 是一个设计系统,它定义了一套中后台设计与前端基础组',
- });
- export const SelectSize = () => (
- <div
- style={{
- margin: 20,
- }}
- >
- <h4>
- 使用方不设width时,下拉菜单根据内容自动适配宽度(不推荐这样使用,select的宽度会动态变化)
- </h4>
- <Select
- defaultValue={'all'}
- optionList={options}
- style={{
- margin: 10,
- }}
- ></Select>
- <Select
- defaultValue={'long'}
- optionList={longOptions}
- style={{
- margin: 10,
- }}
- ></Select>
- <Select
- defaultValue={'abc'}
- size="large"
- optionList={options}
- style={{
- margin: 10,
- }}
- ></Select>
- {/* <Select defaultValue={'+86'} size="large" optionList={options} style={{margin: 10}}>
- </Select> */}
- <h4>通过style设width的</h4>
- 90px:{' '}
- <Select
- defaultValue={'all'}
- style={{
- width: 90,
- marign: 10,
- }}
- optionList={options}
- ></Select>
- 120px:{' '}
- <Select
- defaultValue={'all'}
- style={{
- width: 120,
- margin: 10,
- }}
- optionList={options}
- ></Select>
- 400px:{' '}
- <Select
- defaultValue={'all'}
- style={{
- width: 400,
- margin: 10,
- }}
- optionList={options}
- ></Select>
- <br />
- 100%:{' '}
- <Select
- defaultValue={'all'}
- style={{
- width: '100%',
- margin: 10,
- }}
- optionList={options}
- ></Select>
- <br />
- <h4>通过css设width的</h4>
- <Select defaultValue={'all'} className="test-width" optionList={options}></Select>
- <br />
- <h4>dropdownMatchSelectWidth</h4>
- <p>当该项设为true时,下拉菜单最小宽度会等于Select宽度(默认为true)</p>
- <div
- style={{
- margin: 10,
- }}
- >
- style方式指定90px:
- <Select
- defaultValue={'all'}
- optionList={options}
- dropdownMatchSelectWidth={true}
- style={{
- width: 90,
- }}
- />
- </div>
- <div
- style={{
- margin: 10,
- }}
- >
- css方式声明130px:
- <Select
- defaultValue={'all'}
- className="test-width"
- optionList={options}
- dropdownMatchSelectWidth={true}
- ></Select>
- </div>
- <div>
- <h4>需要强制下拉菜单与select同宽的时候</h4>
- <p>通过dropdownStyle覆盖min-width,将其设成与select的width同样的值</p>
- <Select
- defaultValue={'all'}
- style={{
- width: 300,
- margin: 10,
- }}
- dropdownStyle={{
- width: 300,
- }}
- optionList={options}
- />
- </div>
- </div>
- );
- SelectSize.story = {
- name: 'select size',
- };
- export const WithPrefixSuffixInsetLabelShowClearShowArrow = () => (
- <>
- <h4>prefix & suffix</h4>
- <Select
- style={{
- width: '250px',
- }}
- optionList={options}
- prefix={<IconSearch />}
- suffix={<IconGift></IconGift>}
- ></Select>
- <h4>insetLabel</h4>
- <Select
- style={{
- width: '250px',
- }}
- optionList={options}
- insetLabel={'业务线'}
- ></Select>
- <h4>showClear</h4>
- <Select
- style={{
- width: '250px',
- }}
- optionList={options}
- showClear
- ></Select>
- <h4>showArrow = false</h4>
- <Select
- style={{
- width: '250px',
- }}
- optionList={options}
- showArrow={false}
- ></Select>
- <h4>defaultValue是不存在的值</h4>
- <Select
- style={{
- width: '250px',
- }}
- optionList={options}
- defaultValue="+85"
- ></Select>
- </>
- );
- WithPrefixSuffixInsetLabelShowClearShowArrow.story = {
- name: 'with prefix / suffix / insetLabel, showClear, showArrow',
- };
- WithPrefixSuffixInsetLabelShowClearShowArrow.parameters = {
- chromatic: { disableSnapshot: false },
- };
- export const WithDefaultSelected = () => (
- <Select
- style={{
- width: '250px',
- }}
- defaultValue={1}
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- </Select>
- );
- WithDefaultSelected.story = {
- name: 'with default selected',
- };
- export const WithScrollbar = () => (
- <Select
- style={{
- width: '250px',
- }}
- defaultValue={1}
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value="8">opt8</Option>
- <Option value={9}>opt9</Option>
- <Option value={10}>opt10dfsdfsdfdsfdsfsdf</Option>
- <Option value={11}>opt11</Option>
- <Option value="12">opt12jfldsjflsdjlfldjslfjhifsdfdsfdsffdsodsjlfhjl</Option>
- </Select>
- );
- WithScrollbar.story = {
- name: 'with scrollbar',
- };
- class Link extends React.Component {
- get provinces() {
- return ['Sichuan', 'Guangdong'];
- }
- get maps() {
- return {
- Sichuan: ['Chengdu', 'Dujiangyan'],
- Guangdong: ['Guangzhou', 'Shenzhen', 'Dongguan'],
- };
- }
- constructor() {
- super();
- this.state = {
- provinces: this.provinces,
- maps: this.maps,
- citys: this.maps[this.provinces[0]],
- city: this.maps[this.provinces[0]][0],
- };
- this.provinceChange = this.provinceChange.bind(this);
- this.cityChange = this.cityChange.bind(this);
- }
- provinceChange(newProvince) {
- const { maps } = this.state;
- this.setState({
- citys: maps[newProvince],
- city: maps[newProvince][0],
- });
- }
- cityChange(city) {
- this.setState({
- city,
- });
- }
- render() {
- const { provinces, citys, city } = this.state;
- return (
- <React.Fragment>
- <Select
- style={{
- width: '150px',
- margin: '10px',
- }}
- onChange={this.provinceChange}
- defaultValue={provinces[0]}
- >
- {provinces.map(pro => (
- <Option value={pro} key={pro}>
- {pro}
- </Option>
- ))}
- </Select>
- <Select
- style={{
- width: '150px',
- margin: '10px',
- }}
- value={city}
- onChange={this.cityChange}
- >
- {citys.map(c => (
- <Option value={c} key={c}>
- {c}
- </Option>
- ))}
- </Select>
- </React.Fragment>
- );
- }
- }
- export const TwoSelectChangeAtTheSameTime = () => <Link />;
- TwoSelectChangeAtTheSameTime.story = {
- name: 'two select change at the same time',
- };
- export const SelectMultiple = () => (
- <>
- <Select
- multiple={true}
- max={10}
- style={{
- width: '180px',
- }}
- placeholder="fefe"
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- <br />
- <br />
- <Select
- multiple={true}
- style={{
- width: '300px',
- }}
- defaultValue={[1, 2, 3]}
- placeholder="fefe"
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- <br />
- <br />
- <Select
- multiple={true}
- style={{
- width: '300px',
- }}
- defaultValue={[1, 2, 3]}
- placeholder="fefe"
- disabled
- onSelect={(...res) => console.log(res)}
- onDeselect={(...res) => console.log(res)}
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- <br />
- <br />
- maxTagCount = 3
- <Select
- multiple={true}
- maxTagCount={3}
- style={{
- width: '350px',
- }}
- defaultValue={[1, 2, 3]}
- placeholder="fefe"
- insetLabel="标签"
- onSelect={(...res) => console.log(res)}
- onDeselect={(...res) => console.log(res)}
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- <br />
- <br />
- maxTagCount = 3, max=5
- <Select
- multiple={true}
- maxTagCount={3}
- max={5}
- style={{
- width: '350px',
- }}
- defaultValue={[1, 2, 3]}
- placeholder="fefe"
- insetLabel="标签"
- onSelect={(...res) => console.log(res)}
- onDeselect={(...res) => console.log(res)}
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- </>
- );
- SelectMultiple.story = {
- name: 'select multiple',
- };
- SelectMultiple.parameters = {
- chromatic: { disableSnapshot: false },
- };
- export const SelectDisabled = () => (
- <Select
- disabled
- multiple={true}
- max={10}
- style={{
- width: '250px',
- }}
- >
- <Option value={1}>opt1</Option>
- <Option value={2} disabled>
- opt2
- </Option>
- <Option value={3}>opt3</Option>
- <Option value="4">opt4</Option>
- </Select>
- );
- SelectDisabled.story = {
- name: 'select disabled',
- };
- function filter(input, option) {
- console.log(option);
- return option.label.includes(input);
- }
- const spanStyle = {
- display: 'inline-block',
- marginRight: '8px',
- width: '16px',
- height: '16px',
- borderRadius: '50%',
- border: '1px solid var(--semi-color-bg-1)',
- };
- const colorOptions = [
- {
- value: 'grey-1',
- spanStyle: { ...spanStyle, backgroundColor: 'rgb(107, 116, 117)' },
- },
- {
- value: 'purple-5',
- spanStyle: { ...spanStyle, backgroundColor: 'rgb(158, 40, 179)' },
- },
- {
- value: 'pink-2',
- spanStyle: { ...spanStyle, backgroundColor: 'rgb(233, 30, 99)' },
- },
- {
- value: 'blue-3',
- spanStyle: { ...spanStyle, backgroundColor: 'rgb(0, 119, 250)' },
- },
- ];
- const alignStyle = {
- display: 'flex',
- alignItems: 'center',
- };
- const customFilter = (input, option) => {
- return option.value.includes(input);
- };
- export const SelectFilterSingle = () => (
- <div>
- <h5>默认筛选</h5>
- <Select
- filter
- style={{
- width: '250px',
- margin: 10,
- }}
- showClear
- autoFocus
- onSearch={(val) => console.log(`onSearch:${val}`)}
- onFocus={() => console.log('onFocus')}
- onBlur={() => console.log('onBlur')}
- >
- <Option value={1}>opt1</Option>
- <Option value={2} disabled>
- disabled
- </Option>
- <Option value={3}>Lucy</Option>
- <Option value="4">bay</Option>
- <Option value="5">sert</Option>
- <Option value="6">wym</Option>
- <Option value="7" disabled>
- meno
- </Option>
- <Option value="8">opts</Option>
- </Select>
- <h5>自定义筛选函数</h5>
- <Select
- style={{
- width: '250px',
- margin: 10,
- }}
- filter={filter}
- showClear
- onBlur={() => console.log('onBlur')}
- onSearch={val => console.log(val)}
- onFocus={() => console.log('onFocus')}
- >
- <Option value={1}>opt1(value:1)</Option>
- <Option value={2}>mike(value:2)</Option>
- <Option value={3}>Lucy(value:3)</Option>
- <Option value={4}>bay(value:4)</Option>
- </Select>
- <h5>filter为true,但option label为node时</h5>
- <Select
- style={{
- width: '250px',
- margin: 10,
- }}
- showClear
- filter={customFilter}
- onChange={v => console.log(v)}
- insetLabel="insetLabel"
- onFocus={() => console.log('onFocus')}
- onBlur={() => console.log('onBlur')}
- onSearch={(val) => console.log(val)}
- >
- {colorOptions.map(option => (
- <Option value={option.value} key={option.value}>
- <div style={alignStyle}>
- <span style={option.spanStyle}></span>
- {option.value}
- </div>
- </Option>
- ))}
- </Select>
- </div>
- );
- SelectFilterSingle.story = {
- name: 'select filter single',
- };
- export const SelectFilterMultiple = () => (
- <>
- <Select
- filter
- multiple={true}
- style={{
- width: '250px',
- }}
- placeholder="fefe"
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt22</Option>
- <Option value={3}>opt3</Option>
- <Option value={4}>opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- <Select
- filter
- multiple={true}
- maxTagCount={3}
- style={{
- width: '270px',
- }}
- placeholder="fefe"
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt22</Option>
- <Option value={3}>opt3</Option>
- <Option value={4}>opt4</Option>
- <Option value={5}>opt5</Option>
- <Option value={6}>opt6</Option>
- <Option value={7}>opt7</Option>
- <Option value={8}>opt8</Option>
- </Select>
- </>
- );
- SelectFilterMultiple.story = {
- name: 'select filter multiple',
- };
- const OptionLabelProp = () => {
- const [value, setValue] = useState(1);
- return (
- <>
- 设置optionLabelProp属性(默认为'children')为'value'时,回填到选择框中的文本会是Option.value
- <br></br>
- <Select
- style={{
- width: '250px',
- }}
- defaultValue={1}
- optionLabelProp="value"
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>
- <span
- style={{
- color: 'pink',
- }}
- >
- opt3 Node
- </span>
- </Option>
- <Option value="4">
- <span
- style={{
- color: 'red',
- }}
- >
- testNode
- </span>
- </Option>
- </Select>
- <br />
- <br />
- <Select
- style={{
- width: '250px',
- }}
- value={value}
- optionLabelProp="value"
- onChange={setValue}
- >
- <Option value={1}>opt1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>
- <span
- style={{
- color: 'pink',
- }}
- >
- opt3 Node
- </span>
- </Option>
- <Option value="4">
- <span
- style={{
- color: 'red',
- }}
- >
- testNode
- </span>
- </Option>
- </Select>
- <br />
- <br />
- <Select
- style={{
- width: '250px',
- }}
- defaultValue={1}
- >
- <Option value={1}>children Label Text 1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">
- <span
- style={{
- color: 'red',
- }}
- >
- testNode
- </span>
- </Option>
- </Select>
- <Select
- style={{
- width: '250px',
- }}
- defaultValue={1}
- filter
- optionLabelProp="value"
- >
- <Option value={1}>children Label Text 1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">
- <span
- style={{
- color: 'red',
- }}
- >
- testNode
- </span>
- </Option>
- </Select>
- <br />
- <br />
- 多选
- <Select
- style={{
- width: '250px',
- }}
- multiple
- filter
- optionLabelProp="value"
- >
- <Option value={1}>children Label Text 1</Option>
- <Option value={2}>opt2</Option>
- <Option value={3}>opt3</Option>
- <Option value="4">
- <span
- style={{
- color: 'red',
- }}
- >
- testNode
- </span>
- </Option>
- </Select>
- </>
- );
- };
- class CustomRender extends React.Component {
- constructor() {
- super();
- this.state = {
- list: [
- {
- name: '夏可漫',
- email: '[email protected]',
- abbr: 'XK',
- color: 'amber',
- },
- {
- name: '申悦',
- email: '[email protected]',
- abbr: 'SY',
- color: 'indigo',
- },
- {
- name: '曲晨一',
- email: '[email protected]',
- abbr: 'CY',
- color: 'blue',
- },
- {
- name: '文嘉茂',
- email: '[email protected]',
- abbr: 'JM',
- color: 'cyan',
- },
- ],
- };
- }
- renderCustomOption(item, index) {
- const optionStyle = {
- display: 'flex',
- };
- return (
- <Option key={index} value={item.name} style={optionStyle} showTick={false} {...item}>
- <Avatar color={item.color} size="small">
- {item.abbr}
- </Avatar>
- <div
- style={{
- marginLeft: 4,
- }}
- >
- <p
- style={{
- fontSize: 14,
- margin: 4,
- }}
- >
- {item.name}
- </p>
- <p
- style={{
- margin: 4,
- }}
- >
- {item.email}
- </p>
- </div>
- </Option>
- );
- }
- renderSelectedItem(optionNode) {
- return (
- <div>
- <Avatar color={optionNode.color} size="small">
- {optionNode.abbr}
- </Avatar>
- <span
- style={{
- margin: 8,
- }}
- >
- {optionNode.email}
- </span>
- </div>
- );
- }
- renderMultipleSelectedItem(optionNode) {
- let content = (
- <div>
- <Avatar color={optionNode.color} size="small">
- {optionNode.abbr}
- </Avatar>
- </div>
- );
- return {
- isRenderInTag: true,
- content,
- };
- }
- renderMultipleWithoutTag(optionNode) {
- let content = (
- <div>
- <Avatar color={optionNode.color} size="small">
- {optionNode.abbr}
- </Avatar>
- </div>
- );
- return {
- isRenderInTag: false,
- content,
- };
- }
- render() {
- const { list } = this.state;
- return (
- <React.Fragment>
- <Select
- style={{
- width: 300,
- height: 40,
- }}
- onChange={this.provinceChange}
- defaultValue={'夏可漫'}
- renderSelectedItem={this.renderSelectedItem}
- >
- {list.map((item, index) => this.renderCustomOption(item, index))}
- </Select>
- <Select
- style={{
- width: 360,
- height: 60,
- marginTop: 20,
- }}
- onChange={this.provinceChange}
- defaultValue={['夏可漫', '申悦']}
- multiple
- renderSelectedItem={this.renderMultipleSelectedItem}
- >
- {list.map((item, index) => this.renderCustomOption(item, index))}
- </Select>
- <Select
- style={{
- width: 360,
- height: 60,
- marginTop: 20,
- }}
- onChange={this.provinceChange}
- defaultValue={['夏可漫', '申悦']}
- multiple
- renderSelectedItem={this.renderMultipleWithoutTag}
- >
- {list.map((item, index) => this.renderCustomOption(item, index))}
- </Select>
- </React.Fragment>
- );
- }
- }
- export const RenderSelectedItem = () => (
- <>
- renderSelectedItem
- <CustomRender />
- <br />
- <br />
- OptionLabelProp
- <OptionLabelProp />
- </>
- );
- RenderSelectedItem.story = {
- name: 'renderSelectedItem',
- };
- RenderSelectedItem.parameters = {
- chromatic: { disableSnapshot: false },
- };
- const ControlledSelect = () => {
- const [value, setValue] = useState('nick');
- const [value2, setValue2] = useState('jerry');
- const [value3, setValue3] = useState();
- const [value4, setValue4] = useState(['nick']);
- const [value5, setValue5] = useState();
- return (
- <>
- <span>value + onChange</span>
- <Select
- value={value}
- onChange={setValue}
- style={{
- width: 200,
- }}
- >
- <Option value="nick">nick</Option>
- <Option value="jerry">jerry</Option>
- <Option value="mark">mark</Option>
- </Select>
- <br />
- <br />
- <span>只传value,不传onChange</span>
- <Select
- value={value2}
- style={{
- width: 200,
- }}
- >
- <Option value="nick">nick</Option>
- <Option value="jerry">jerry</Option>
- <Option value="mark">mark</Option>
- </Select>
- <br />
- <br />
- <span>value + onChange , 多选</span>
- <Select
- value={value3}
- onChange={setValue3}
- multiple
- style={{
- width: 200,
- }}
- >
- <Option value="nick">nick</Option>
- <Option value="jerry">jerry</Option>
- <Option value="mark">mark</Option>
- <Option value="nick2">nick2</Option>
- <Option value="jerry2">jerry2</Option>
- <Option value="mark2">mark2</Option>
- </Select>
- <br />
- <br />
- <span>value, 多选</span>
- <Select
- value={value4}
- multiple
- style={{
- width: 200,
- }}
- >
- <Option value="nick">nick</Option>
- <Option value="jerry">jerry</Option>
- <Option value="mark">mark</Option>
- </Select>
- <br />
- <h5>filter为true,但option label为node时</h5>
- <Select
- style={{
- width: '250px',
- }}
- filter={customFilter}
- onChange={v => console.log(v)}
- insetLabel="insetLabel"
- value={value5}
- onChange={setValue5}
- >
- {colorOptions.map(option => (
- <Option value={option.value} key={option.value}>
- <div style={alignStyle}>
- <span style={option.spanStyle}></span>
- {option.value}
- </div>
- </Option>
- ))}
- </Select>
- </>
- );
- };
- export const Controlled = () => <ControlledSelect></ControlledSelect>;
- Controlled.story = {
- name: 'controlled',
- };
- const UnControlledSelect = () => {
- const onChange = value => {
- console.log(value);
- };
- return (
- <>
- <h5>defaultValue在list中不存在</h5>
- <Select
- defaultValue={90}
- onChange={onChange}
- style={{
- width: 200,
- }}
- >
- <Option value={20}>nick</Option>
- <Option value={10}>jerry</Option>
- <Option value={5}>mark</Option>
- </Select>
- <h5>defaultValue在list中存在</h5>
- <Select
- defaultValue={10}
- onChange={onChange}
- style={{
- width: 200,
- }}
- >
- <Option value={20}>nick</Option>
- <Option value={10}>jerry</Option>
- <Option value={5}>mark</Option>
- </Select>
- </>
- );
- };
- export { UnControlledSelect };
- UnControlledSelect.story = {
- name: '非受控组件'
- };
- export const TestScroll = () => (
- <div
- style={{
- marginTop: '600px',
- marginBottom: '50px',
- }}
- >
- <Select
- style={{
- width: '150px',
- }}
- >
- <Option value="tony">IronMan</Option>
- <Option value="Thor" disabled>
- Thor
- </Option>
- <Option value="steve">Caption</Option>
- <Option value="peter">SpiderBoy</Option>
- </Select>
- </div>
- );
- TestScroll.story = {
- name: 'test scroll',
- };
- let optionList = [
- {
- value: 'tony',
- label: 'Ironman',
- },
- {
- value: 'Thor',
- label: 'Thor',
- },
- {
- value: 'steve',
- label: 'Caption',
- },
- {
- value: 'peter',
- label: 'SpiderBoy',
- },
- ];
- export const OptionList = () => (
- <Select
- style={{
- width: '100px',
- }}
- optionList={optionList}
- ></Select>
- );
- OptionList.story = {
- name: 'optionList',
- };
- export const InsetLabel = () => (
- <>
- <Select
- style={{
- width: 300,
- }}
- insetLabel="主播类型"
- placeholder="请选择"
- optionList={optionList}
- ></Select>
- <Select
- style={{
- width: 300,
- }}
- multiple
- insetLabel="主播类型"
- optionList={optionList}
- ></Select>
- <Select
- style={{
- width: 300,
- }}
- filter
- insetLabel="主播类型"
- optionList={optionList}
- ></Select>
- <Select
- style={{
- width: 300,
- }}
- filter
- multiple
- insetLabel="主播类型"
- optionList={optionList}
- ></Select>
- </>
- );
- InsetLabel.story = {
- name: 'insetLabel',
- };
- export const ChangeOptionDynamic = () => {
- function App() {
- let [options, setOptions] = useState([]);
- let [index, setIndex] = useState(0);
- const addOption = () => {
- const randomItem = optionList[index];
- index = index + 1;
- setIndex(index);
- options = [...options, { ...randomItem }];
- setOptions(options);
- };
- const reset = () => {
- setOptions([]);
- setIndex(0);
- };
- return (
- <div>
- <Select
- style={{
- width: '150px',
- }}
- defaultValue="tony"
- >
- {options.map((option, idx) => (
- <Select.Option key={option.key || idx} value={option.value}>
- {option.label}
- </Select.Option>
- ))}
- </Select>
- <h4>多选</h4>
- <Select
- style={{
- width: '150px',
- }}
- multiple
- defaultValue={['tony']}
- >
- {options.map((option, idx) => (
- <Select.Option key={option.key || idx} value={option.value}>
- {option.label}
- </Select.Option>
- ))}
- </Select>
- <button onClick={addOption}>add option</button>
- <button onClick={reset}>reset</button>
- </div>
- );
- }
- return <App />;
- };
- ChangeOptionDynamic.story = {
- name: 'change option dynamic',
- };
- let list = [
- {
- value: 'tony',
- label: 'Ironman',
- otherKey: {
- role: 1,
- },
- },
- {
- value: 'Thor',
- label: 'Thor',
- otherKey: {
- role: 2,
- },
- },
- {
- value: 'steve',
- label: 'Caption',
- otherKey: {
- role: 3,
- },
- },
- {
- value: 'peter',
- label: 'SpiderBoy',
- otherKey: {
- role: 4,
- },
- },
- ];
- const SearchDemo1 = () => {
- const [optionList, setOptionList] = useState(list);
- const [loading, setLoading] = useState(false);
- const handleSearch = value => {
- setLoading(true);
- let length = Math.ceil(Math.random() * 10);
- let result = Array.from(
- {
- length,
- },
- (v, i) => {
- return {
- value: value + i,
- label: value + i,
- otherKey: {
- role: i,
- },
- };
- }
- );
- setTimeout(() => {
- setOptionList(result);
- setLoading(false);
- }, 1000);
- };
- const [value, setValue] = useState(optionList[0].value);
- const onChange = value => {
- console.log(value);
- setValue(value);
- };
- return (
- <div>
- 受控:
- <Select
- filter
- style={{
- width: '150px',
- }}
- onSearch={v => handleSearch(v)}
- optionList={optionList}
- value={value}
- loading={loading}
- showClear
- onChange={onChange}
- ></Select>
- 非受控:
- <Select
- style={{
- width: '150px',
- }}
- filter
- showClear
- onSearch={v => handleSearch(v)}
- optionList={optionList}
- loading={loading}
- onChange={onChange}
- ></Select>
- 多选非受控
- <Select
- style={{
- width: '150px',
- }}
- showClear
- filter
- multiple
- onSearch={v => handleSearch(v)}
- optionList={optionList}
- loading={loading}
- onChange={onChange}
- ></Select>
- </div>
- );
- };
- import debounce from 'lodash/debounce';
- class SearchDemo2 extends React.Component {
- constructor() {
- super();
- this.state = {
- loading: false,
- optionList: [
- {
- value: 'abc',
- label: '抖音',
- type: 1,
- },
- {
- value: 'hotsoon',
- label: '火山小视频',
- type: 2,
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- type: 3,
- },
- {
- value: 'toutiao',
- label: '今日头条',
- type: 4,
- },
- ],
- value: [],
- };
- this.handleSearch = debounce(this.handleSearch, 800).bind(this);
- this.onChange = this.onChange.bind(this);
- this.customRender = this.customRender.bind(this);
- }
- handleSearch(inputValue) {
- this.setState({
- loading: true,
- });
- let length = Math.ceil(Math.random() * 100);
- let result = Array.from(
- {
- length,
- },
- (v, i) => {
- return {
- value: inputValue + i,
- label: 'label' + i,
- type: i + 1,
- };
- }
- );
- setTimeout(() => {
- this.setState({
- optionList: result,
- loading: false,
- });
- }, 2000);
- }
- onChange(value) {
- this.setState({
- value,
- });
- console.log(value);
- }
- customRender(optionNode) {
- return optionNode.value + optionNode.label;
- }
- render() {
- const { loading, optionList, value } = this.state;
- return (
- <div>
- <Select
- style={{
- width: 150,
- }}
- showClear
- filter
- labelInValue
- onSearch={this.handleSearch}
- optionList={optionList}
- loading={loading}
- onChange={this.onChange}
- placeholder="请选择"
- ></Select>
- <br />
- <br />
- <Select
- style={{
- width: 180,
- }}
- filter // labelInValue
- showClear
- multiple
- value={value}
- renderSelectedItem={this.customRender}
- onSearch={this.handleSearch}
- optionList={optionList}
- loading={loading}
- onChange={this.onChange}
- placeholder="请选择"
- ></Select>
- </div>
- );
- }
- }
- export const Search = () => (
- <>
- <SearchDemo1 />
- <SearchDemo2 />
- </>
- );
- Search.story = {
- name: 'search',
- };
- export const IncomeDetail = ({ config = {}, params = {} }) => {
- const [detailList, setDetailList] = useState([]);
- const [hasMore, setHasMore] = useState(true);
- const [loading, setLoading] = useState();
- let lock;
- const fetchData = (outParams = {}) => {
- if (lock) {
- return;
- }
- setLoading(true); // 参数
- // 请求
- fetch({
- url: URL.user_profit,
- method: 'get',
- baseURL: config.webcast_host,
- params,
- })
- .then(res => {
- lock = false;
- setLoading(false);
- console.log('++++', data);
- })
- .catch(() => {
- setLoading(false);
- Toast.show('网络异常,请稍后重试');
- });
- };
- useEffect(fetchData, []); // 监听滚动设置吸顶 以及加载更多
- useEffect(() => {
- window.addEventListener('scroll', function() {
- // 加载更多
- const scrollY = window.scrollY;
- const scrollHeight = document.documentElement.scrollHeight;
- const screenHeight = screen.height;
- if (!loading && hasMore && scrollY + screenHeight + 300 > scrollHeight) {
- fetchData();
- }
- });
- }, [detailList.length]);
- return (
- <div>
- <Select></Select>
- </div>
- );
- };
- export const AllowCreate = () => (
- <Select
- style={{
- width: 500,
- }}
- optionList={optionList}
- allowCreate={true}
- multiple={true}
- filter={true}
- onChange={v => console.log(v)}
- ></Select>
- );
- AllowCreate.story = {
- name: 'allowCreate',
- };
- export const AllowCreateCustomRender = () => (
- <Select
- style={{
- width: 500,
- }}
- optionList={optionList}
- allowCreate={true}
- multiple={true}
- filter={true}
- onChange={v => console.log(v)}
- renderCreateItem={v => `semi: ${v}`}
- ></Select>
- );
- AllowCreateCustomRender.story = {
- name: 'allowCreate custom render',
- };
- let AllowCreateControlledDemo = () => {
- let [value, setValue] = useState();
- const optionList = [
- {
- value: 'abc',
- label: '抖音',
- },
- {
- value: 'hotsoon',
- label: '火山小视频',
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- },
- {
- value: 'toutiao',
- label: '今日头条',
- },
- ];
- const [list, setList] = useState(optionList);
- const handleSelect = v => {
- var lastOne = v[v.length - 1];
- if (lastOne && list.findIndex(item => item.value === lastOne) == -1) {
- list.push({
- value: lastOne,
- label: lastOne,
- });
- }
- setList(list);
- setValue(v);
- };
- return (
- <Select
- style={{
- width: 400,
- }}
- optionList={list}
- allowCreate={true}
- multiple={true}
- filter={true}
- value={value}
- onChange={handleSelect}
- ></Select>
- );
- };
- const AllowCreateDemo = () => {
- let [value, setValue] = useState();
- const optionList = [
- {
- value: 'abc',
- label: '抖音',
- },
- {
- value: 'hotsoon',
- label: '火山小视频',
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- },
- {
- value: 'toutiao',
- label: '今日头条',
- },
- ];
- const [list, setList] = useState(optionList);
- const handleSelect = v => {
- var lastOne = v[v.length - 1];
- if (lastOne && list.findIndex(item => item.value === lastOne) == -1) {
- list.push({
- value: lastOne,
- label: lastOne,
- });
- }
- setList(list); // setValue(v)
- };
- return (
- <Select
- style={{
- width: 400,
- }}
- optionList={list}
- defaultValue={['abc', 'hotsoon']}
- allowCreate={true}
- multiple={true}
- filter={true}
- onChange={handleSelect}
- ></Select>
- );
- };
- export const AllowCreateWithDefaultValue = () => <AllowCreateDemo />;
- AllowCreateWithDefaultValue.story = {
- name: 'allowCreate with defaultValue',
- };
- class HideDemo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- optionList: [
- {
- value: 'abc',
- label: '抖音',
- },
- {
- value: 'hotsoon',
- label: '火山小视频',
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- },
- {
- value: 'toutiao',
- label: '今日头条',
- },
- ],
- selectedItems: [],
- };
- this.onChange = this.onChange.bind(this);
- }
- onChange(selectedItems) {
- this.setState({
- selectedItems,
- });
- }
- render() {
- let { optionList, selectedItems } = this.state;
- let filterOptions = optionList.filter(option => !selectedItems.includes(option.value));
- return (
- <Select
- value={selectedItems}
- multiple
- style={{
- width: 300,
- }}
- onChange={this.onChange}
- optionList={filterOptions}
- ></Select>
- );
- }
- }
- export const AutoHiddenSelectedItem = () => <HideDemo></HideDemo>;
- AutoHiddenSelectedItem.story = {
- name: 'auto hidden selected item',
- };
- class CustomCreate extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- optionList: [
- {
- value: 'abc',
- label: '抖音',
- },
- {
- value: 'hotsoon',
- label: '火山小视频',
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- },
- {
- value: 'toutiao',
- label: '今日头条',
- },
- {
- value: 0,
- label: 0,
- },
- ],
- selectedItems: ['fefe'],
- };
- this.onChange = this.onChange.bind(this);
- this.customRender = this.customRender.bind(this);
- this.search = this.search.bind(this);
- }
- onChange(selectedItems) {
- console.log(selectedItems); // this.setState({ selectedItems, optionList: [] });
- this.setState({
- selectedItems,
- }); // this.setState({ optionList: [] });
- }
- customRender(v) {
- return (
- <>
- <span>label:{v.label}</span>
- <span>value:{v.value}</span>
- </>
- );
- }
- customCreate(inputValue, isFocus) {
- let style = {
- padding: 12,
- cursor: 'pointer',
- backgroundColor: isFocus ? 'var(--semi-color-fill-0)' : '#FFF',
- };
- return <div style={style}>{'create' + inputValue}</div>;
- }
- search(inputValue) {
- let length = Math.ceil(Math.random() * 10);
- let result = Array.from(
- {
- length,
- },
- (v, i) => {
- return {
- value: inputValue + i,
- label: inputValue + i,
- type: i + 1,
- };
- }
- );
- console.log(result); // result = result.concat(selectedOption);
- this.setState({
- optionList: result,
- });
- }
- render() {
- let { optionList, selectedItems } = this.state;
- return (
- <>
- <Select
- defaultValue={['abc']}
- filter
- style={{
- width: 300,
- }}
- multiple
- optionList={optionList}
- onSearch={this.search}
- onChange={this.onChange}
- emptyContent={null} // onChangeWithObject
- ></Select>
- </>
- );
- }
- }
- export const _CustomCreate = () => <CustomCreate></CustomCreate>;
- _CustomCreate.story = {
- name: 'CustomCreate',
- };
- class OptionGroupDemo extends React.Component {
- constructor(props) {
- super(props);
- this.handleSearch = this.handleSearch.bind(this);
- this.state = {
- groups: [
- {
- label: 'Asia',
- children: [
- {
- label: 'China',
- value: 'zhongguo',
- },
- {
- label: 'Koera',
- value: 'hanguo',
- },
- ],
- },
- {
- label: 'Europe',
- children: [
- {
- label: 'Germany',
- value: 'deguo',
- },
- {
- label: 'France',
- value: 'faguo',
- },
- ],
- },
- {
- label: 'Other',
- children: [
- {
- label: 'vf',
- value: 'Sourth',
- },
- ],
- },
- ],
- };
- }
- handleSearch(input) {
- let groups = [1, 2, 3].map(i => {
- return {
- label: i,
- // label: Math.random(),
- children: [10, 20].map(j => {
- return {
- label: Math.random(),
- value: Math.random(),
- };
- }),
- };
- });
- this.setState({
- groups,
- });
- }
- renderGroup(group, index) {
- const options = group.children.map(option => (
- <Select.Option value={option.value} label={option.label} key={option.label} />
- ));
- return <Select.OptGroup key={`${index}-${group.label}`} label={group.label}>{options}</Select.OptGroup>;
- }
- render() {
- const { groups } = this.state;
- return (
- <>
- <Select
- placeholder=""
- style={{
- width: 180,
- }}
- filter
- onSearch={this.handleSearch}
- remote
- >
- {groups.map((group, index) => this.renderGroup(group, index))}
- </Select>
- </>
- );
- }
- }
- export const SelectOptionGroup = () => <OptionGroupDemo />;
- SelectOptionGroup.story = {
- name: 'Select OptionGroup',
- };
- const BlurDemo = () => {
- const onBlur = (value, e) => {
- console.log(value);
- console.log(e);
- };
- const onFocus = (value, e) => {
- console.log(value);
- console.log(e);
- };
- return (
- <>
- <Select
- filter
- placeholder=""
- style={{
- width: 180,
- }}
- onBlur={onBlur}
- onFocus={onFocus}
- >
- <Select.Option value="zhongguo">China</Select.Option>
- <Select.Option value="hanguo">Koera</Select.Option>
- <Select.Option value="deguo">Germany</Select.Option>
- <Select.Option value="faguo">France</Select.Option>
- </Select>
- </>
- );
- };
- export const SelectOnBlurOnFocus = () => <BlurDemo></BlurDemo>;
- SelectOnBlurOnFocus.story = {
- name: 'Select onBlur/onFocus',
- };
- const AutoAdjustOverflowDemo = () => {
- const [list, setList] = useState([
- {
- value: 'abc',
- label: '1111',
- },
- {
- value: 'hotsoon',
- label: '1112',
- },
- {
- value: 'pipixia',
- label: '1113',
- },
- {
- value: 'toutiao',
- label: '1114',
- },
- ]);
- const onSearch = () => {
- let newList = Array.from(
- {
- length: Math.floor(Math.random() * 10),
- },
- (v, i) => {
- return {
- value: i,
- label: i,
- };
- }
- );
- setList(newList);
- console.log(newList);
- };
- return (
- <div
- style={{
- height: 180,
- margin: 250,
- border: '1px solid pink',
- }}
- >
- <Select
- optionList={list}
- filter={true}
- remote={true}
- onSearch={onSearch}
- style={{
- width: 200,
- }}
- multiple
- />
- </div>
- );
- };
- export const AutoAdjustOverflow = () => <AutoAdjustOverflowDemo></AutoAdjustOverflowDemo>;
- AutoAdjustOverflow.story = {
- name: 'autoAdjustOverflow',
- };
- const AllowCreateWithFilter = () => {
- const [list, setList] = useState([
- {
- value: 'abc',
- label: 'abc',
- otherKey: 'abc',
- },
- {
- value: 'hotsoon',
- label: 'hotsoon',
- otherKey: 'efg',
- },
- {
- value: 'pipixia',
- label: 'pipixia',
- otherKey: 'hij',
- },
- {
- value: 'toutiao',
- label: 'toutiao',
- otherKey: 'klm',
- },
- ]);
- const filter = (sugInput, option) => {
- let compareKey = option.otherKey ? option.otherKey.toUpperCase() : '';
- let sug = sugInput.toUpperCase();
- return compareKey.includes(sug);
- };
- return (
- <div
- style={{
- height: 180,
- margin: 250,
- }}
- >
- <Select
- optionList={list}
- multiple
- filter={filter}
- style={{
- width: 200,
- }}
- allowCreate
- />
- </div>
- );
- };
- export const FilterAllowCreate = () => <AllowCreateWithFilter></AllowCreateWithFilter>;
- FilterAllowCreate.story = {
- name: 'Filter + allowCreate',
- };
- const SelectRefDemo = () => {
- const ref = useRef();
- const secondRef = useRef();
- const [open, setOpen] = useState(false);
- const list = [
- {
- value: 'abc',
- label: 'Abc',
- },
- {
- value: 'hotsoon',
- label: 'Hotsoon',
- },
- {
- value: 'pipixia',
- label: 'Pipixia',
- },
- {
- value: 'toutiao',
- label: 'TooBuzz',
- },
- ];
- const change = () => {
- if (!open) {
- ref.current.open();
- setOpen(true);
- } else {
- ref.current.close();
- setOpen(false);
- }
- };
- const focus = () => {
- ref.current.focus();
- };
- const clearInput = () => {
- ref.current.clearInput();
- };
- const deselectAll = () => {
- ref.current.deselectAll();
- };
- const selectAll = () => {
- ref.current.selectAll();
- };
- return (
- <>
- <h4>onChangeWithObject = false</h4>
- <Select
- innerBottomSlot={
- <div>
- <Space>
- <Button onClick={change}>close</Button>
- <Button onClick={clearInput}>clearInput</Button>
- <Button onClick={deselectAll}>deselectAll</Button>
- <Button onClick={selectAll}>selectAll</Button>
- </Space>
- </div>
- }
- ref={ref}
- onChange={e => console.log(e)}
- placeholder="Business line"
- style={{
- width: 180,
- }}
- optionList={list}
- filter
- multiple
- ></Select>
- <Space>
- <Button onClick={change}>open</Button>
- <Button onClick={focus}>focus</Button>
- <Button onClick={clearInput}>clearInput</Button>
- <Button onClick={deselectAll}>deselectAll</Button>
- <Button onClick={selectAll}>selectAll</Button>
- </Space>
- <h4
- style={{
- marginTop: 20,
- }}
- >
- onChangeWithObject = true
- </h4>
- <Select
- innerBottomSlot={
- <div>
- <Space></Space>
- </div>
- }
- onChange={e => console.log(e)}
- onChangeWithObject
- ref={secondRef}
- placeholder="Business line"
- style={{
- width: 180,
- }}
- optionList={list}
- filter
- multiple
- ></Select>
- <Space>
- <Button onClick={() => secondRef.current.deselectAll()}>deselectAll</Button>
- <Button onClick={() => secondRef.current.selectAll()}>selectAll</Button>
- </Space>
- </>
- );
- };
- export const Ref = () => <SelectRefDemo />;
- Ref.story = {
- name: 'ref',
- };
- export const CustomTriggerDemo = () => <CustomTrigger />;
- CustomTriggerDemo.story = {
- name: 'custom trigger'
- }
- class VirtualizeClassDemo extends React.Component {
- constructor(props) {
- super(props);
- // this.handleSearch = this.handleSearch.bind(this);
- let newOptions = Array.from({ length: 1000 }, (v, i) => ({ label: `o-${i}`, value: `v-${v}-${i}` }));
- this.state = {
- optionList: newOptions,
- };
- }
- render() {
- let { groups, optionList } = this.state;
- let virtualize = {
- height: 300,
- widht: '100%',
- itemSize: 36,
- };
- return (
- <>
- <Select
- placeholder=""
- style={{ width: 180 }}
- filter
- onSearch={this.handleSearch}
- virtualize={virtualize}
- optionList={optionList}
- ></Select>
- </>
- );
- }
- }
- export const VirtualizeDemo = () => <VirtualizeClassDemo />;
- VirtualizeDemo.story = {
- name: 'virtualize select'
- }
- const SelectPosition = () => {
- return (
- <div
- style={{
- height: 500,
- border: '1px solid red',
- overflow: 'auto',
- }}
- >
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <Select
- defaultValue="abc"
- style={{
- width: 120,
- }}
- >
- <Option value="abc">抖音</Option>
- <Option value="hotsoon">火山</Option>
- <Option value="pipixia" disabled>
- 皮皮虾
- </Option>
- <Option value="xigua">西瓜视频</Option>
- </Select>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- <p>p</p>
- </div>
- );
- };
- export { SelectPosition };
- SelectPosition.story = {
- name: 'Select position problem'
- }
- const RenderOptionDemo = () => {
- const renderOptionItem = renderProps => {
- const {
- disabled,
- selected,
- label,
- value,
- focused,
- className,
- style,
- onMouseEnter,
- onClick,
- empty,
- emptyContent,
- ...rest
- } = renderProps;
- const optionCls = classNames({
- ['custom-option-render']: true,
- ['custom-option-render-focused']: focused,
- ['custom-option-render-disabled']: disabled,
- ['custom-option-render-selected']: selected,
- }); // Notice:
- // 1.props传入的style需在wrapper dom上进行消费,否则在虚拟化场景下会无法正常使用
- // 2.选中(selected)、聚焦(focused)、禁用(disabled)等状态的样式需自行加上,你可以从props中获取到相对的boolean值
- // 3.onMouseEnter需在wrapper dom上绑定,否则上下键盘操作时显示会有问题
- return (
- <div
- style={style}
- className={optionCls}
- onClick={() => onClick()}
- onMouseEnter={e => onMouseEnter()}
- >
- <Checkbox checked={selected} />
- <div className="option-right">{label}</div>
- </div>
- );
- };
- return (
- <>
- <Select
- filter
- dropdownClassName="components-select-demo-renderOptionItem"
- optionList={optionList}
- style={{
- width: 300,
- }}
- renderOptionItem={renderOptionItem}
- />
- <br />
- <br />
- <Select
- filter
- multiple
- dropdownClassName="components-select-demo-renderOptionItem"
- optionList={optionList}
- style={{
- width: 450,
- }}
- renderOptionItem={renderOptionItem}
- />
- </>
- );
- };
- export const RenderOptionItem = () => <RenderOptionDemo />;
- RenderOptionItem.story = {
- name: 'renderOptionItem',
- };
- const FilterDefaultOpen = () => {
- const [value1, setValue1] = useState('a-1');
- return (
- <>
- <Select
- placeholder=""
- style={{
- width: 180,
- }}
- filter
- defaultOpen
- >
- <Select.OptGroup label="Asia">
- <Select.Option value="a-1">China</Select.Option>
- <Select.Option value="a-2">Koera</Select.Option>
- </Select.OptGroup>
- <Select.OptGroup label="Europe">
- <Select.Option value="b-1">Germany</Select.Option>
- <Select.Option value="b-2">France</Select.Option>
- </Select.OptGroup>
- <Select.OptGroup label="South America">
- <Select.Option value="c-1">Peru</Select.Option>
- </Select.OptGroup>
- </Select>
- <Select
- placeholder=""
- style={{
- width: 180,
- marginLeft: 20,
- }}
- filter
- defaultOpen
- defaultValue="a-2"
- >
- <Select.OptGroup label="Asia">
- <Select.Option value="a-1">China</Select.Option>
- <Select.Option value="a-2">Koera</Select.Option>
- </Select.OptGroup>
- <Select.OptGroup label="Europe">
- <Select.Option value="b-1">Germany</Select.Option>
- <Select.Option value="b-2">France</Select.Option>
- </Select.OptGroup>
- <Select.OptGroup label="South America">
- <Select.Option value="c-1">Peru</Select.Option>
- </Select.OptGroup>
- </Select>
- <Select
- placeholder=""
- style={{
- width: 180,
- marginLeft: 20,
- }}
- filter
- defaultOpen
- value={value1}
- onChange={val => setValue1(val)}
- >
- <Select.Option value="a-1">China</Select.Option>
- <Select.Option value="a-2">Koera</Select.Option>
- <Select.Option value="b-1">Germany</Select.Option>
- <Select.Option value="b-2">France</Select.Option>
- <Select.Option value="c-1">Peru</Select.Option>
- </Select>
- </>
- );
- };
- export { FilterDefaultOpen };
- FilterDefaultOpen.story = {
- name: 'Filter + defaultOpen'
- };
- const CustomSelect = props => {
- const { fieldRef, ...rest } = props;
- return <Select {...rest} ref={fieldRef} />;
- };
- const CustomFieldSelect = withField(CustomSelect);
- const RefDemo = () => {
- const fieldRef = useRef(null);
- const onChange = () => {
- console.log(fieldRef);
- fieldRef.current.open();
- debugger;
- };
- return (
- <Form>
- <CustomFieldSelect field="test" initValue="se" fieldRef={fieldRef}></CustomFieldSelect>
- <Button onClick={onChange}>change</Button>
- </Form>
- );
- };
- export const RefFieldDemo = () => <RefDemo />;
- RefFieldDemo.story = {
- name: 'Ref field demo',
- };
- const ValueZeroDemo = () => {
- const list = [
- {
- value: 6,
- label: '抖音小视频',
- otherKey: 0,
- },
- {
- value: 1,
- label: '火山小视频',
- disabled: true,
- otherKey: 1,
- },
- {
- value: 'pipixia',
- label: '皮皮虾',
- otherKey: 2,
- },
- {
- value: 'toutiao',
- label: '今日头条',
- otherKey: 3,
- },
- ];
- return (
- <Select
- placeholder="请选择业务线"
- style={{
- width: 180,
- }}
- optionList={list}
- value={0}
- renderSelectedItem={option => option.label + 1}
- ></Select>
- );
- };
- export const Value0 = () => <ValueZeroDemo />;
- Value0.story = {
- name: 'value=0',
- };
- const Highlight = () => {
- const searchWords = ['do', 'dollar'];
- const sourceString = 'aaa do dollar aaa';
- const result = getHighLightTextHTML({
- searchWords,
- sourceString,
- });
- const result2 = getHighLightTextHTML({
- searchWords: ['z'],
- sourceString: 'aaazaaazaaa',
- });
- return result2;
- };
- export const _Highlight = () => <Highlight />;
- _Highlight.story = {
- name: 'highlight',
- };
- export const ScrollIntoView = () => (
- <div>
- <p>single selection</p>
- <Select defaultValue='v-11' defaultOpen style={{ width: 120, marginBottom: 300 }}>
- {new Array(50).fill(null).map((item, idx) => (
- <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
- ))}
- </Select>
- <p>single selection with no selected item</p>
- <Select style={{ marginBottom: 300, width: 120 }}>
- {new Array(50).fill(null).map((item, idx) => (
- <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
- ))}
- </Select>
- <p>The selected node is the last</p>
- <Select defaultValue='v-49' defaultOpen style={{ marginBottom: 300, width: 120 }}>
- {new Array(50).fill(null).map((item, idx) => (
- <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
- ))}
- </Select>
- <p>The selected node is the first</p>
- <Select defaultValue='v-0' style={{ marginBottom: 300, width: 120 }}>
- {new Array(50).fill(null).map((item, idx) => (
- <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
- ))}
- </Select>
- <p>multiple selection</p>
- <Select defaultValue={['v-25', 'v-9']} multiple style={{ marginBottom: 300, width: 220 }}>
- {new Array(30).fill(null).map((item, idx) => (
- <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
- ))}
- </Select>
- <p>multiple selection with no selected item</p>
- <Select multiple style={{ marginBottom: 300, width: 220 }}>
- {new Array(30).fill(null).map((item, idx) => (
- <Option value={`v-${idx}`} key={idx}>{`option-${idx}`}</Option>
- ))}
- </Select>
- </div>
- );
- ScrollIntoView.story = {
- name: 'scroll into view',
- };
- export const SelectInputPropsDemo = () => {
- const inputProps = {
- className: 'ttt',
- onCompositionEnd: (v) => console.log(v.target.value)
- };
- return (
- <Select
- // onSearch={(v) => console.log(v)}
- optionList={list}
- inputProps={inputProps}
- multiple
- filter
- style={{ width: 200 }}
- >
- </Select>
- )
- };
- SelectInputPropsDemo.story = {
- name: 'inputProps',
- };
- export const AutoClearSearchValue = () => {
- const [val, setVal] = useState(['semi1']);
- const optionList = [
- { label: 'semi1', value: 'semi1' },
- { label: 'semi2', value: 'semi2' },
- { label: 'semi3', value: 'semi3' },
- { label: 'semi4', value: 'semi4' },
- { label: 'semi5', value: 'semi5' },
- { label: 'semi6', value: 'semi6' },
- ];
- return (
- <>
- <h4>Controlled mode + multiple</h4>
- <Select style={{ width: 400 }} multiple optionList={optionList} filter value={val} onChange={value => setVal(value)} autoClearSearchValue={false}></Select>
- <br />
- <br />
- <h4>Uncontrolled mode + multiple</h4>
- <Select style={{ width: 400 }} multiple optionList={optionList} filter autoClearSearchValue={false}></Select>
- <h4>Uncontrolled mode + multiple + defaultValue</h4>
- <Select style={{ width: 400 }} multiple optionList={optionList} filter defaultValue={['semi2']} autoClearSearchValue={false}></Select>
- </>
- )
- }
- SelectInputPropsDemo.story = {
- name: 'AutoClearSearchValue',
- };
- export const RenderSelectedItemCallCount = () => {
- const list = [
- { "name": "夏可漫", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg" },
- { "name": "申悦", "email": "[email protected]", "avatar": "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg" },
- { "name": "曲晨一", "email": "[email protected]", "avatar": "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/8bd8224511db085ed74fea37205aede5.jpg" },
- { "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" },
- { "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" },
- { "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" },
- ]
- const renderMultipleWithCustomTag = (optionNode, { onClose }) => {
- console.count('rerender')
- const content = (
- <Tag
- avatarSrc={optionNode.avatar}
- avatarShape='circle'
- closable={true}
- onClose={onClose}
- size='large'
- >
- {optionNode.name}
- </Tag>
- );
- return {
- isRenderInTag: false,
- content
- };
- }
- const renderCustomOption = (item, index) => {
- const optionStyle = {
- display: 'flex',
- paddingLeft: 24,
- paddingTop: 10,
- paddingBottom: 10
- }
- return (
- <Select.Option key={index} value={item.name} style={optionStyle} showTick={true} {...item} key={item.email}>
- <Avatar size="small" src={item.avatar} />
- <div style={{ marginLeft: 8 }}>
- <div style={{ fontSize: 14 }}>{item.name}</div>
- <div style={{ color: 'var(--color-text-2)', fontSize: 12, lineHeight: '16px', fontWeight: 'normal' }}>{item.email}</div>
- </div>
- </Select.Option>
- )
- }
- return (
- <>
- <Select
- placeholder='请选择'
- showClear
- multiple
- maxTagCount={2}
- style={{ width: 280, height: 40 }}
- onChange={v => console.log(v)}
- defaultValue={'夏可漫'}
- renderSelectedItem={renderMultipleWithCustomTag}
- >
- {list.map((item, index) => renderCustomOption(item, index))}
- </Select>
- </>
- );
- }
- RenderSelectedItemCallCount.story = {
- name: 'RenderSelectedItemCallCount',
- };
|