12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906 |
- import React, { useState, useRef, useEffect } from 'react';
- import './select.scss';
- import { Input, Select, Button, Icon, Avatar, Checkbox, Form, withField, Space } 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,
- }}
- autoFocus
- 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}
- onBlur={() => console.log('onBlur')}
- 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,
- }}
- filter={customFilter}
- onChange={v => console.log(v)}
- insetLabel="insetLabel"
- onFocus={() => console.log('onFocus')}
- onBlur={() => console.log('onBlur')}
- >
- {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 ControledSelect = () => {
- 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 = () => <ControledSelect></ControledSelect>;
- Controlled.story = {
- name: 'controlled',
- };
- const UnControledSelect = () => {
- 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 { UnControledSelect };
- UnControledSelect.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}
- onChange={onChange}
- ></Select>
- 非受控:
- <Select
- style={{
- width: '150px',
- }}
- filter
- onSearch={v => handleSearch(v)}
- optionList={optionList}
- loading={loading}
- onChange={onChange}
- ></Select>
- 多选非受控
- <Select
- style={{
- width: '150px',
- }}
- 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,
- }}
- filter
- labelInValue
- onSearch={this.handleSearch}
- optionList={optionList}
- loading={loading}
- onChange={this.onChange}
- placeholder="请选择"
- ></Select>
- <br />
- <br />
- <Select
- style={{
- width: 180,
- }}
- filter // labelInValue
- 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 AllowCreateControledDemo = () => {
- 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',
- };
|