input.stories.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. import React, { useState, useCallback } from 'react';
  2. import GraphemeSplitter from 'grapheme-splitter';
  3. import { isFunction, isString } from 'lodash';
  4. import {
  5. Input,
  6. InputGroup,
  7. TextArea,
  8. TimePicker,
  9. DatePicker,
  10. AutoComplete,
  11. Cascader,
  12. Select,
  13. TagInput,
  14. Tree,
  15. TreeSelect,
  16. Icon,
  17. TabPane,
  18. Tabs,
  19. Button,
  20. Typography,
  21. Switch,
  22. Form,
  23. Space,
  24. Radio,
  25. InputNumber
  26. } from '../../index';
  27. import './input.scss';
  28. import RTLWrapper from '../../configProvider/_story/RTLDirection/RTLWrapper';
  29. import { IconSearch, IconCopy, IconClear, IconStar } from '@douyinfe/semi-icons';
  30. export default {
  31. title: 'Input',
  32. parameters: {
  33. chromatic: { disableSnapshot: true },
  34. }
  35. }
  36. const { Title, Text } = Typography;
  37. const log = (...args) => console.log(...args);
  38. export const _Input = () => (
  39. <div
  40. className="input"
  41. style={{
  42. width: 200,
  43. }}
  44. >
  45. <Input />
  46. <Input validateStatus="warning" />
  47. <Input validateStatus="error" />
  48. <br />
  49. <br />
  50. <Input size="large" />
  51. <Input size="large" validateStatus="warning" />
  52. <Input size="large" validateStatus="error" />
  53. <br />
  54. <br />
  55. <Input size="small" />
  56. <Input size="small" validateStatus="warning" />
  57. <Input size="small" validateStatus="error" />
  58. </div>
  59. );
  60. _Input.parameters = {
  61. chromatic: { disableSnapshot: false },
  62. };
  63. export const InputAutofocus = () => (
  64. <div className="input">
  65. <Input placeholder="ies input" autofocus />
  66. </div>
  67. );
  68. InputAutofocus.story = {
  69. name: 'Input autofocus',
  70. };
  71. export const InputPlaceholder = () => (
  72. <div className="input">
  73. <Input placeholder="ies input" />
  74. </div>
  75. );
  76. InputPlaceholder.story = {
  77. name: 'Input placeholder',
  78. };
  79. export const InputDisabled = () => (
  80. <div className="input">
  81. <Input disabled value="禁用文本框值" />
  82. </div>
  83. );
  84. InputDisabled.parameters = {
  85. chromatic: { disableSnapshot: false },
  86. };
  87. InputDisabled.story = {
  88. name: 'Input disabled',
  89. };
  90. export const InputClearable = () => (
  91. <div className="input">
  92. <Input showClear defaultValue="ies" />
  93. </div>
  94. );
  95. InputClearable.story = {
  96. name: 'Input clearable',
  97. };
  98. export const InputPrefixSuffixDemo = () => (
  99. <div className="input">
  100. <Input prefix="search" showClear defaultValue="Semi Design" />
  101. <Input prefix={<span>pre</span>} showClear defaultValue="Semi Design" />
  102. <Input prefix={<span>pre</span>} showClear defaultValue="Semi Design" />
  103. <Input suffix={<IconSearch />} autofocus showClear defaultValue="Semi Design"></Input>
  104. <Input suffix="Semi Design" showClear defaultValue="Semi Design"></Input>
  105. <Input
  106. suffix={
  107. <Typography.Text
  108. strong
  109. type="secondary"
  110. style={{
  111. margin: '0 8px',
  112. }}
  113. >
  114. Suffix
  115. </Typography.Text>
  116. }
  117. showClear
  118. defaultValue="Semi Design"
  119. ></Input>
  120. </div>
  121. );
  122. InputPrefixSuffixDemo.story = {
  123. name: '前缀/后缀 Input prefix suffix',
  124. };
  125. InputPrefixSuffixDemo.parameters = {
  126. chromatic: { disableSnapshot: false },
  127. };
  128. export const InputAddonBeforeAddonAfter = () => (
  129. <div className="input">
  130. <Input addonBefore="https://" addonAfter=".com" />
  131. </div>
  132. );
  133. InputAddonBeforeAddonAfter.story = {
  134. name: '前置/后置标签 Input addonBefore addonAfter',
  135. };
  136. InputAddonBeforeAddonAfter.parameters = {
  137. chromatic: { disableSnapshot: false },
  138. };
  139. export const InputPassword = () => (
  140. <div className="input">
  141. <Input mode="password" placeholder="请输入密码" />
  142. <Input mode="password" defaultValue="ies" />
  143. <Input mode="password" showClear defaultValue="ies" />
  144. <Input mode="password" disabled defaultValue="ies" />
  145. </div>
  146. );
  147. InputPassword.story = {
  148. name: 'Input password',
  149. };
  150. InputPassword.parameters = {
  151. chromatic: { disableSnapshot: false },
  152. };
  153. export const ControlInput = () => {
  154. const [value, setValue] = useState('initString');
  155. return (
  156. <div className="input">
  157. <Input value={value} onChange={setValue} showClear />
  158. <Input value={value} onChange={log} showClear />
  159. </div>
  160. );
  161. };
  162. ControlInput.story = { name: '受控组件' };
  163. export const UnControlInput = () => (
  164. <div className="input">
  165. <Input onChange={v => console.log(v)} defaultValue="initString" />
  166. </div>
  167. );
  168. UnControlInput.story = { name: '非受控组件' };
  169. export const Password = () => (
  170. <div className="input">
  171. <Input type="password" />
  172. </div>
  173. );
  174. Password.story = {
  175. name: 'password',
  176. };
  177. const treeData = [
  178. {
  179. label: '亚洲',
  180. value: 'Asia',
  181. key: '0',
  182. children: [
  183. {
  184. label: '中国',
  185. value: 'China',
  186. key: '0-0',
  187. children: [
  188. {
  189. label: '北京',
  190. value: 'Beijing',
  191. key: '0-0-0',
  192. },
  193. {
  194. label: '上海',
  195. value: 'Shanghai',
  196. key: '0-0-1',
  197. },
  198. ],
  199. },
  200. ],
  201. },
  202. {
  203. label: '北美洲',
  204. value: 'North America',
  205. key: '1',
  206. },
  207. ];
  208. export const Group = () => (
  209. <div className="input">
  210. <InputGroup>
  211. <Select
  212. placeholder="Name"
  213. style={{
  214. width: 100,
  215. }}
  216. optionList={[
  217. {
  218. value: 1,
  219. label: 1,
  220. },
  221. {
  222. value: 2,
  223. label: 2,
  224. },
  225. ]}
  226. />
  227. <Select
  228. placeholder="Score"
  229. style={{
  230. width: 140,
  231. }}
  232. optionList={[
  233. {
  234. value: 1,
  235. label: 1,
  236. },
  237. {
  238. value: 2,
  239. label: 2,
  240. },
  241. ]}
  242. />
  243. </InputGroup>
  244. <br />
  245. <br />
  246. {/* <InputGroup>
  247. <Input placeholder="Name" style={{ width: 100 }} />
  248. <InputNumber placeholder="Score" style={{ width: 140 }} />
  249. </InputGroup>
  250. <br/><br/>
  251. <InputGroup size={'small'}>
  252. <Select style={{ width: '100px' }} defaultValue='home'>
  253. <Option value='home'>Home</Option>
  254. <Option value='work'>Work</Option>
  255. </Select>
  256. <AutoComplete
  257. data={['Beijing Haidian']}
  258. placeholder='Address: '
  259. style={{ width: 180 }}
  260. >
  261. </AutoComplete>
  262. </InputGroup>
  263. <br/><br/>
  264. <InputGroup size={'small'}>
  265. <Select style={{ width: '100px' }} defaultValue='signup'>
  266. <Option value='signup'>Sign Up</Option>
  267. <Option value='signin'>Sign In</Option>
  268. </Select>
  269. <Input placeholder="Email" style={{ width: 180 }} />
  270. </InputGroup>
  271. <br/><br/>
  272. <InputGroup>
  273. <Select style={{ width: '100px' }} defaultValue='signup'>
  274. <Option value='signup'>Sign Up</Option>
  275. <Option value='signin'>Sign In</Option>
  276. </Select>
  277. <TreeSelect
  278. style={{ width: 300 }}
  279. treeData={treeData}
  280. placeholder="Please select"
  281. />
  282. </InputGroup>
  283. <br/><br/>
  284. <InputGroup>
  285. <Select style={{ width: 100 }} defaultValue='signup'>
  286. <Option value='signup'>Sign Up</Option>
  287. <Option value='signin'>Sign In</Option>
  288. </Select>
  289. <TreeSelect
  290. style={{ width: 300 }}
  291. treeData={treeData}
  292. placeholder="Please select"
  293. />
  294. <Cascader
  295. style={{ width: 300 }}
  296. treeData={treeData}
  297. placeholder="Please select"
  298. />
  299. </InputGroup> */}
  300. </div>
  301. );
  302. Group.story = {
  303. name: 'group',
  304. };
  305. Group.parameters = {
  306. chromatic: { disableSnapshot: false },
  307. };
  308. export const Textarea = () => <TextArea limit={100} onChange={v => console.log(v)} />;
  309. Textarea.story = {
  310. name: 'textarea',
  311. };
  312. export const AutosizeTextarea = () => (
  313. <div className="input">
  314. <TextArea autosize onChange={v => console.log(v)} />
  315. {/* <TextArea autosize limit={500} onChange={v => console.log(v)} />
  316. <TextArea autosize rows={1} onChange={v => console.log(v)} /> */}
  317. </div>
  318. );
  319. AutosizeTextarea.story = {
  320. name: 'autosize textarea',
  321. };
  322. export const TextareaInnerMaxCount = () => (
  323. <div className="input">
  324. <TextArea defaultValue="TextArea without maxCount" />
  325. <br />
  326. <br />
  327. <TextArea maxCount={10} defaultValue="0123456789" />
  328. <br />
  329. <br />
  330. <TextArea maxCount={10} defaultValue="Semi Design System exceed maxCount" />
  331. <br />
  332. <br />
  333. <TextArea maxCount={10} defaultValue="Semi Design System autosize" autosize rows={2} />
  334. <br />
  335. <br />
  336. <TextArea maxCount={10} defaultValue="Semi Design System disabled" disabled />
  337. <br />
  338. <br />
  339. <TextArea maxCount={10} defaultValue="Semi Design System readonly" readonly />
  340. <br />
  341. <br />
  342. <TextArea maxCount={10} defaultValue="Semi Design System warning" validateStatus="warning" />
  343. <br />
  344. <br />
  345. <TextArea maxCount={10} defaultValue="Semi Design System error" validateStatus="error" />
  346. <br />
  347. <br />
  348. <TextArea maxCount={10} defaultValue="Semi Design System normal" validateStatus="normal" />
  349. <br />
  350. <br />
  351. </div>
  352. );
  353. TextareaInnerMaxCount.story = {
  354. name: 'textarea inner maxCount ',
  355. };
  356. TextareaInnerMaxCount.parameters = {
  357. chromatic: { disableSnapshot: false },
  358. };
  359. class RefDemo extends React.Component {
  360. constructor() {
  361. super();
  362. this.state = {
  363. loading: false,
  364. };
  365. this.inputRef = React.createRef();
  366. this.focus = this.focus.bind(this);
  367. }
  368. focus(inputValue) {
  369. console.log(this.inputRef);
  370. debugger;
  371. this.inputRef.current.focus();
  372. }
  373. render() {
  374. return (
  375. <div>
  376. <Input ref={this.inputRef} />
  377. <Button onClick={this.focus}>focus</Button>
  378. </div>
  379. );
  380. }
  381. }
  382. class TARefDemo extends React.Component {
  383. constructor() {
  384. super();
  385. this.ref = React.createRef();
  386. this.focus = this.focus.bind(this);
  387. this.blur = this.blur.bind(this);
  388. }
  389. focus(val) {
  390. console.log(this.ref, val);
  391. this.ref.current.focus();
  392. }
  393. blur() {
  394. this.ref.current.blur();
  395. }
  396. render() {
  397. return (
  398. <div>
  399. <TextArea ref={this.ref} />
  400. <Button onClick={this.focus}>focus</Button>
  401. <Button onClick={this.blur}>blur</Button>
  402. </div>
  403. );
  404. }
  405. }
  406. export const InputRefDemo = () => (
  407. <>
  408. <RefDemo />
  409. <TARefDemo />
  410. </>
  411. );
  412. InputRefDemo.story = {
  413. name: 'ref的使用',
  414. };
  415. export const InputHideSuffix = () => (
  416. <div className="input" onClick={() => console.log('clicking DIV....')}>
  417. <Input suffix={<IconCopy onClick={() => console.log('clicking')} />} showClear hideSuffix />
  418. </div>
  419. );
  420. InputHideSuffix.story = {
  421. name: 'Input hideSuffix',
  422. };
  423. InputHideSuffix.parameters = {
  424. chromatic: { disableSnapshot: false },
  425. };
  426. export const TextareaInTabPane = () => (
  427. <div>
  428. <Tabs type="line">
  429. <TabPane tab="文档" itemKey="1">
  430. <TextArea
  431. autosize={true}
  432. value={
  433. '卡垃圾速度快;发神经地方;京阿是;大家;发生空间的浪费空间阿莱克斯\n决定分开了京阿是快进到风口浪尖阿斯顿克己复礼卡就是快乐减肥空间就是快乐的健康京阿是快的\n解放路口京阿是来对\n抗肌肤阿就是大家阿节点空间阿斯顿空间卡经典款九分裤阿是加快立法开始饭卡空间发考\n虑时间快放假啊肯德基快放辣椒的;放假啊;江东父老卡快放假\n啊快到家快放假啊的快乐减肥咖哩鸡的卡上看到肌肤卡经典空间卡;框架'
  434. }
  435. />
  436. </TabPane>
  437. <TabPane tab="快速起步" itemKey="2">
  438. <TextArea
  439. autosize={true}
  440. value={
  441. '1234\n卡垃圾速度快;发神经地方;京阿是;大家;发生空间的浪费空间阿莱克斯\n决定分开了京阿是快进到风口浪尖阿斯顿克己复礼卡就是快乐减肥空间就是快乐的健康京阿是快的\n解放路口京阿是来对\n抗肌肤阿就是大家阿节点空间阿斯顿空间卡经典款九分裤阿是加快立法开始饭卡空间发考\n虑时间快放假啊肯德基快放辣椒的;放假啊;江东父老卡快放假\n啊快到家快放假啊的快乐减肥咖哩鸡的卡上看到肌肤卡经典空间卡;框架'
  442. }
  443. />
  444. </TabPane>
  445. </Tabs>
  446. </div>
  447. );
  448. TextareaInTabPane.story = {
  449. name: 'Textarea in TabPane',
  450. };
  451. const ControlTextarea = () => {
  452. const [value, setValue] = useState('initString');
  453. return (
  454. <>
  455. <TextArea value={value} onChange={setValue} />
  456. <br />
  457. <TextArea value={value} onChange={setValue} autosize />
  458. </>
  459. );
  460. };
  461. export const ControlledTextarea = () => <ControlTextarea />;
  462. ControlledTextarea.story = {
  463. name: '受控textarea'
  464. }
  465. export const FixAddonBeforeShowClear = () => (
  466. <Space wrap>
  467. <Input
  468. style={{
  469. width: 300,
  470. }}
  471. autofocus
  472. defaultValue="Semi Design"
  473. addonBefore="http://"
  474. showClear
  475. />
  476. <Input
  477. style={{
  478. width: 300,
  479. }}
  480. defaultValue="Semi Design"
  481. addonBefore="http://"
  482. addonAfter=".com"
  483. showClear
  484. />
  485. <Input
  486. style={{
  487. width: 300,
  488. }}
  489. defaultValue="Semi Design"
  490. showClear
  491. />
  492. <Input
  493. style={{
  494. width: 300,
  495. }}
  496. defaultValue="Semi Design"
  497. addonBefore="http://"
  498. />
  499. <Input
  500. style={{
  501. width: 300,
  502. }}
  503. defaultValue="Semi Design"
  504. />
  505. <Input
  506. style={{
  507. width: 300,
  508. }}
  509. defaultValue="Semi Design"
  510. addonBefore="http://"
  511. showClear
  512. validateStatus="warning"
  513. />
  514. <Input
  515. style={{
  516. width: 300,
  517. }}
  518. defaultValue="Semi Design"
  519. addonBefore="http://"
  520. showClear
  521. validateStatus="error"
  522. />
  523. <Input
  524. style={{
  525. width: 300,
  526. }}
  527. defaultValue="Semi Design"
  528. addonBefore="http://"
  529. mode="password"
  530. showClear
  531. />
  532. <Input
  533. style={{
  534. width: 300,
  535. }}
  536. defaultValue="Semi Design"
  537. addonBefore="http://"
  538. addonAfter=".com"
  539. mode="password"
  540. showClear
  541. />
  542. <Input
  543. style={{
  544. width: 300,
  545. }}
  546. defaultValue="Semi Design"
  547. addonBefore="http://"
  548. addonAfter=".com"
  549. mode="password"
  550. showClear
  551. size="small"
  552. />
  553. <Input
  554. style={{
  555. width: 300,
  556. }}
  557. defaultValue="Semi Design"
  558. addonBefore="http://"
  559. addonAfter=".com"
  560. mode="password"
  561. showClear
  562. size="large"
  563. />
  564. </Space>
  565. );
  566. FixAddonBeforeShowClear.story = {
  567. name: 'fix addonBefore + showClear',
  568. };
  569. FixAddonBeforeShowClear.parameters = {
  570. chromatic: { disableSnapshot: false },
  571. };
  572. export const FocusWhenClickPrefixSuffix = () => (
  573. <Space wrap>
  574. <Input
  575. style={{ width: 200 }}
  576. onFocus={() => console.log('focused')}
  577. prefix="search"
  578. defaultValue="Semi Design"
  579. />
  580. <Input
  581. style={{ width: 200 }}
  582. onFocus={() => console.log('focused')}
  583. onBlur={() => {
  584. console.log('blur');
  585. }}
  586. suffix={<IconSearch />}
  587. defaultValue="Semi Design"
  588. ></Input>
  589. <Input
  590. disabled
  591. style={{ width: 200 }}
  592. onFocus={() => console.log('focused')}
  593. prefix="search"
  594. suffix={<IconSearch />}
  595. defaultValue="disabled"
  596. />
  597. </Space>
  598. );
  599. FocusWhenClickPrefixSuffix.story = {
  600. name: 'focus when click prefix/suffix',
  601. };
  602. export const GetValueLengthEmojiLengthProcess = () => {
  603. function getValueLength(str) {
  604. if (isString(str)) {
  605. const splitter = new GraphemeSplitter();
  606. return splitter.countGraphemes(str);
  607. } else {
  608. return -1;
  609. }
  610. }
  611. const [getVisibleLengthFC, setGetVisibleLength] = useState(() => getValueLength);
  612. const [value, setValue] = useState();
  613. const handleSwitch = useCallback(value => {
  614. if (value) {
  615. setGetVisibleLength(() => getValueLength);
  616. } else {
  617. setGetVisibleLength(value);
  618. }
  619. }, []);
  620. const strExceed10 = '0123456789semi design';
  621. return (
  622. <div className="input">
  623. <div>
  624. <Title
  625. heading={6}
  626. style={{
  627. margin: 8,
  628. }}
  629. >
  630. getValueLength = {isFunction(getVisibleLengthFC) ? 'function' : 'null'}
  631. </Title>
  632. <Switch checked={isFunction(getVisibleLengthFC)} onChange={handleSwitch}>
  633. getValueLength
  634. </Switch>
  635. </div>
  636. <h4>maxLength=10</h4>
  637. <Input
  638. maxLength={10}
  639. getValueLength={getVisibleLengthFC}
  640. style={{
  641. width: 200,
  642. }}
  643. />
  644. <h4>controlled mode + maxLength=10</h4>
  645. <Input
  646. value={value}
  647. onChange={value => {
  648. console.log('input change', value);
  649. setValue(value);
  650. }}
  651. maxLength={10}
  652. getValueLength={getVisibleLengthFC}
  653. style={{
  654. width: 200,
  655. }}
  656. />
  657. <h4>controlled mode + given value exceed maxLength</h4>
  658. <div>
  659. <Input
  660. value={strExceed10}
  661. maxLength={10}
  662. getValueLength={getVisibleLengthFC}
  663. style={{
  664. width: 200,
  665. }}
  666. />
  667. {getVisibleLengthFC && (
  668. <Text>{`getValueLength('${strExceed10}')=${getVisibleLengthFC(strExceed10)}`}</Text>
  669. )}
  670. </div>
  671. <h4>maxCount=10</h4>
  672. <TextArea
  673. maxCount={10}
  674. getValueLength={getVisibleLengthFC}
  675. style={{
  676. width: 200,
  677. }}
  678. />
  679. <h4>maxCount=10 + maxLength=10</h4>
  680. <TextArea
  681. maxCount={10}
  682. maxLength={10}
  683. getValueLength={getVisibleLengthFC}
  684. style={{
  685. width: 200,
  686. }}
  687. />
  688. <h4>form.input + minLength=4</h4>
  689. <Form>
  690. <Form.Input
  691. field="username"
  692. minLength={4}
  693. getValueLength={getVisibleLengthFC}
  694. style={{
  695. width: 200,
  696. }}
  697. />
  698. <Button type="primary" htmlType="submit">
  699. 提交
  700. </Button>
  701. </Form>
  702. </div>
  703. );
  704. };
  705. GetValueLengthEmojiLengthProcess.story = {
  706. name: 'getValueLength emoji length process',
  707. };
  708. GetValueLengthEmojiLengthProcess.parameters = {
  709. chromatic: { disableSnapshot: false },
  710. };
  711. const ShowClearTextarea = () => {
  712. const [value, setValue] = useState('initString');
  713. const handleChange = value => {
  714. setValue(value);
  715. };
  716. return (
  717. <>
  718. <div>受控+onFocus/onBlur</div>
  719. <TextArea
  720. value={value}
  721. onChange={v => handleChange(v)}
  722. showClear
  723. onClear={e => console.log('clear', e)}
  724. onFocus={() => console.log('focus')}
  725. onBlur={() => console.log('blur')}
  726. />
  727. <br />
  728. <br />
  729. <div>disabled</div>
  730. <TextArea defaultValue="123" disabled showClear onClear={e => console.log('clear', e)} />
  731. <br />
  732. <br />
  733. <div>readonly</div>
  734. <TextArea defaultValue="123" readonly showClear onClear={e => console.log('clear', e)} />
  735. <br />
  736. <br />
  737. <div>rows=1,cols=1</div>
  738. <TextArea rows={1} cols={1} showClear onClear={e => console.log('clear', e)} />
  739. </>
  740. );
  741. };
  742. export const TextareaShowClear = () => <ShowClearTextarea />;
  743. TextareaShowClear.story = {
  744. name: 'textarea showClear',
  745. };
  746. export const ClearButton = () => {
  747. const [direction, setDirection] = React.useState('ltr');
  748. const treeData = [
  749. {
  750. label: '亚洲',
  751. value: 'Asia',
  752. key: '0',
  753. children: [
  754. {
  755. label: '中国',
  756. value: 'China',
  757. key: '0-0',
  758. children: [
  759. {
  760. label: '北京',
  761. value: 'Beijing',
  762. key: '0-0-0',
  763. },
  764. {
  765. label: '上海',
  766. value: 'Shanghai',
  767. key: '0-0-1',
  768. },
  769. ],
  770. },
  771. ],
  772. },
  773. {
  774. label: '北美洲',
  775. value: 'North America',
  776. key: '1',
  777. },
  778. ];
  779. return (
  780. <RTLWrapper
  781. onDirectionChange={dir => {
  782. console.log('dir', dir);
  783. setDirection(dir);
  784. }}
  785. >
  786. <Input defaultValue="semi" suffix={<IconClear />} />
  787. <Input defaultValue="semi" showClear suffix={<IconStar />} />
  788. <Input
  789. defaultValue="semi"
  790. showClear
  791. suffix={
  792. <Typography.Text
  793. strong
  794. type="secondary"
  795. style={direction === 'ltr' ? { marginRight: 8 } : { marginLeft: 8 }}
  796. >
  797. Suffix
  798. </Typography.Text>
  799. }
  800. />
  801. <Input showClear defaultValue="semi" />
  802. <Input showClear mode="password" defaultValue="semi" />
  803. <Input mode="password" defaultValue="semi" />
  804. <br />
  805. <br />
  806. <Cascader defaultValue="semi design" showClear />
  807. <Select defaultValue="semi design" showClear />
  808. <TagInput defaultValue={['semi design']} showClear />
  809. {/* <Transfer showClear /> */}
  810. <TimePicker defaultValue={new Date()} showClear />
  811. <DatePicker defaultValue={new Date()} showClear />
  812. <Tree filterTreeNode treeData={treeData} showClear />
  813. <TreeSelect defaultValue="semi design" showClear />
  814. </RTLWrapper>
  815. );
  816. };
  817. ClearButton.story = {
  818. name: 'clear button',
  819. };
  820. export const InputFocus = () => {
  821. const ref = React.useRef();
  822. const handleClick = () => {
  823. ref.current.focus();
  824. };
  825. return (
  826. <>
  827. <Button onClick={handleClick}>focus input</Button>
  828. <Input ref={ref} onChange={() => console.log('ref', ref) } onFocus={() => console.log('focus')} />
  829. </>
  830. );
  831. };
  832. export const TextAreaAutosize = () => {
  833. return (
  834. <div style={{ width: 200 }}>
  835. <TextArea autosize />
  836. </div>
  837. )
  838. };
  839. TextAreaAutosize.storyName = "textarea autosize";
  840. export const InputA11y = () => {
  841. return (
  842. <div style={{ width: 300 }}>
  843. <Input prefix="search" defaultValue="Semi Design" showClear />
  844. <br/><br/>
  845. <Input aria-required prefix="search" defaultValue="Semi Design" showClear suffix="semi" />
  846. <br/><br/>
  847. <Input data-cy="password" defaultValue="Semi Design" mode="password" />
  848. <br/><br/>
  849. <Input defaultValue="Semi Design" mode="password" disabled />
  850. <br/><br/>
  851. <Input defaultValue='this value is too long' validateStatus='error' showClear></Input>
  852. <br/><br/>
  853. <TextArea defaultValue='semi' showClear />
  854. <TextArea aria-required defaultValue='不能为空' showClear />
  855. <InputGroup label={{ text: '成绩信息' }}>
  856. <Input placeholder="Name" style={{ width: 100 }} />
  857. <Input placeholder="Score" style={{ width: 140 }} />
  858. </InputGroup>
  859. <br/><br/>
  860. <Form onSubmit={() => alert('submit')}>
  861. <button>submit</button>
  862. <Form.Input field="password" label="密码按钮上敲击 Enter 测试是否会触发 Form submit" mode="password" />
  863. </Form>
  864. </div>
  865. );
  866. }
  867. InputA11y.storyName = "input a11y";
  868. export const FixInputGroup = () => {
  869. const groupFocus = () => {
  870. console.log('group focus');
  871. }
  872. const groupBlur = () => {
  873. console.log('group blur');
  874. }
  875. const inputFocus = () => {
  876. console.log('input focus');
  877. }
  878. const inputBlur = () => {
  879. console.log('input blur');
  880. }
  881. return (
  882. <InputGroup disabled={true} onFocus={groupFocus} onBlur={groupBlur}>
  883. <Input disabled={false} onFocus={inputFocus} onBlur={inputBlur} placeholder="Name" style={{ width: 100 }} />
  884. <InputNumber placeholder="Score" style={{ width: 140 }} />
  885. </InputGroup>
  886. );
  887. }