Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 15x 15x 4x 4x 4x 4x 4x 4x 4x | import React, { forwardRef, useRef, useImperativeHandle } from "react"; import classNames from "classnames"; import { InputProps, Input } from "../input"; import { Button } from "../button"; import { useDefaultValue } from "../form/controlled"; import { ScaleTransition } from "../transition"; import { useConfig } from "../_util/config-context"; export interface SearchBoxProps extends InputProps { /** * 是否为多行搜索模式 * * @default false */ multiline?: boolean; /** * 是否为简洁模式 * * @default false */ simple?: boolean; /** * 点击搜索或输入回车时回调 * 如果自行绑定了 `onKeydown` 处理方法,则该回调不再提供 */ onSearch?: (keyword?: string) => void; /** * 用户清空搜索时回调 * */ onClear?: () => void; /** * 搜索框尺寸 */ size?: "full" | "l" | "m" | "s"; } const noop = () => {}; export const SearchBox = forwardRef(function SearchBox( props: SearchBoxProps, ref: React.Ref<HTMLInputElement | HTMLTextAreaElement> ) { const { classPrefix } = useConfig(); const { multiline, simple, onSearch = noop, onClear = noop, className, style, size, ..._inputProps } = props; const inputBoxClassNames = classNames({ [`${classPrefix}-search`]: true, [`${classPrefix}-search--multi`]: multiline, [`${classPrefix}-search--simple`]: simple, [className]: className, }); const inputProps = useDefaultValue(_inputProps, ""); // 需要使用到 inputRef,同时向外部暴露 const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null); useImperativeHandle(ref, () => inputRef.current); return ( <div className={classNames(`${classPrefix}-form--search`, { [`size-${size === "full" ? `${size}-width` : size}`]: size, })} > <div className={inputBoxClassNames} style={style}> <div className={`${classPrefix}-search__inner`}> <Input type="search" multiline={multiline} baseClassName={`${classPrefix}-input`} className={`${classPrefix}-input--search`} onKeyDown={event => { const { keyCode, ctrlKey, metaKey } = event; if (keyCode === 27) { event.preventDefault(); inputProps.onChange("", { event }); onClear(); } // 回车处理 onSearch 逻辑 if (keyCode !== 13) { return; } // 多行模式下,要按下 ctrl 或者 command if (multiline && !metaKey && !ctrlKey) { return; } event.preventDefault(); onSearch(inputProps.value); }} {...inputProps} ref={inputRef} /> </div> <ScaleTransition in={/\S/.test(inputProps.value)}> <Button icon="dismiss" className={`${classPrefix}-btn--dismiss`} onClick={event => { event.preventDefault(); inputProps.onChange("", { event }); onClear(); if (inputRef.current) { inputRef.current.focus(); } }} /> </ScaleTransition> <Button icon="search" className={`${classPrefix}-btn--search`} onClick={event => { event.preventDefault(); onSearch(inputProps.value); }} /> </div> </div> ); }); |