Skip to content

Commit

Permalink
feat: 优化input 样式问题 (#436)
Browse files Browse the repository at this point in the history
* feat: 优化input 样式问题

* feat: update common

* feat: update common
  • Loading branch information
honkinglin authored Mar 8, 2022
1 parent 7f3834c commit 87b48e3
Show file tree
Hide file tree
Showing 12 changed files with 320 additions and 176 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ exports[`custom-icon.jsx 1`] = `
class="t-input t-is-readonly t-input--prefix t-input--suffix"
>
<span
class="t-input__prefix t-input__suffix-icon"
class="t-input__prefix t-input__prefix-icon"
>
<svg
class="t-icon t-icon-browse"
Expand Down
100 changes: 94 additions & 6 deletions src/form/__tests__/__snapshots__/form.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -557,13 +557,35 @@ exports[`clear-validate.jsx 1`] = `
class="t-input__wrap"
>
<div
class="t-input"
class="t-input t-input--suffix"
>
<input
class="t-input__inner"
type="password"
value=""
/>
<span
class="t-input__suffix t-input__suffix-icon"
>
<svg
class="t-icon t-icon-browse-off t-input__suffix-clear"
fill="none"
height="1em"
viewBox="0 0 16 16"
width="1em"
>
<path
d="M10.77 11.98l1.38 1.37.7-.7-9.7-9.7-.7.7 1.2 1.21a7.9 7.9 0 00-2.53 2.91L1 8l.12.23a7.72 7.72 0 009.65 3.75zM10 11.2A6.67 6.67 0 012.11 8c.56-1 1.34-1.83 2.26-2.43l1.08 1.09a2.88 2.88 0 003.9 3.9l.64.64zM6.21 7.42l2.37 2.37a1.88 1.88 0 01-2.37-2.37zM14.88 8.23L15 8l-.12-.23a7.73 7.73 0 00-9.35-3.86l.8.8A6.7 6.7 0 0113.9 8a6.87 6.87 0 01-2.02 2.26l.7.7a7.9 7.9 0 002.3-2.73z"
fill="currentColor"
fill-opacity="0.9"
/>
<path
d="M10.88 8c0 .37-.07.73-.2 1.06l-.82-.82.02-.24a1.88 1.88 0 00-2.12-1.86l-.82-.82A2.87 2.87 0 0110.88 8z"
fill="currentColor"
fill-opacity="0.9"
/>
</svg>
</span>
</div>
</div>
</div>
Expand Down Expand Up @@ -2011,13 +2033,35 @@ exports[`error-message.jsx 1`] = `
class="t-input__wrap"
>
<div
class="t-input"
class="t-input t-input--suffix"
>
<input
class="t-input__inner"
type="password"
value=""
/>
<span
class="t-input__suffix t-input__suffix-icon"
>
<svg
class="t-icon t-icon-browse-off t-input__suffix-clear"
fill="none"
height="1em"
viewBox="0 0 16 16"
width="1em"
>
<path
d="M10.77 11.98l1.38 1.37.7-.7-9.7-9.7-.7.7 1.2 1.21a7.9 7.9 0 00-2.53 2.91L1 8l.12.23a7.72 7.72 0 009.65 3.75zM10 11.2A6.67 6.67 0 012.11 8c.56-1 1.34-1.83 2.26-2.43l1.08 1.09a2.88 2.88 0 003.9 3.9l.64.64zM6.21 7.42l2.37 2.37a1.88 1.88 0 01-2.37-2.37zM14.88 8.23L15 8l-.12-.23a7.73 7.73 0 00-9.35-3.86l.8.8A6.7 6.7 0 0113.9 8a6.87 6.87 0 01-2.02 2.26l.7.7a7.9 7.9 0 002.3-2.73z"
fill="currentColor"
fill-opacity="0.9"
/>
<path
d="M10.88 8c0 .37-.07.73-.2 1.06l-.82-.82.02-.24a1.88 1.88 0 00-2.12-1.86l-.82-.82A2.87 2.87 0 0110.88 8z"
fill="currentColor"
fill-opacity="0.9"
/>
</svg>
</span>
</div>
</div>
</div>
Expand Down Expand Up @@ -2542,7 +2586,7 @@ exports[`login.jsx 1`] = `
class="t-input t-input--prefix"
>
<span
class="t-input__prefix t-input__suffix-icon"
class="t-input__prefix t-input__prefix-icon"
>
<svg
class="t-icon t-icon-desktop"
Expand Down Expand Up @@ -2581,10 +2625,10 @@ exports[`login.jsx 1`] = `
class="t-input__wrap"
>
<div
class="t-input t-input--prefix"
class="t-input t-input--prefix t-input--suffix"
>
<span
class="t-input__prefix t-input__suffix-icon"
class="t-input__prefix t-input__prefix-icon"
>
<svg
class="t-icon t-icon-lock-on"
Expand All @@ -2611,6 +2655,28 @@ exports[`login.jsx 1`] = `
type="password"
value=""
/>
<span
class="t-input__suffix t-input__suffix-icon"
>
<svg
class="t-icon t-icon-browse-off t-input__suffix-clear"
fill="none"
height="1em"
viewBox="0 0 16 16"
width="1em"
>
<path
d="M10.77 11.98l1.38 1.37.7-.7-9.7-9.7-.7.7 1.2 1.21a7.9 7.9 0 00-2.53 2.91L1 8l.12.23a7.72 7.72 0 009.65 3.75zM10 11.2A6.67 6.67 0 012.11 8c.56-1 1.34-1.83 2.26-2.43l1.08 1.09a2.88 2.88 0 003.9 3.9l.64.64zM6.21 7.42l2.37 2.37a1.88 1.88 0 01-2.37-2.37zM14.88 8.23L15 8l-.12-.23a7.73 7.73 0 00-9.35-3.86l.8.8A6.7 6.7 0 0113.9 8a6.87 6.87 0 01-2.02 2.26l.7.7a7.9 7.9 0 002.3-2.73z"
fill="currentColor"
fill-opacity="0.9"
/>
<path
d="M10.88 8c0 .37-.07.73-.2 1.06l-.82-.82.02-.24a1.88 1.88 0 00-2.12-1.86l-.82-.82A2.87 2.87 0 0110.88 8z"
fill="currentColor"
fill-opacity="0.9"
/>
</svg>
</span>
</div>
</div>
</div>
Expand Down Expand Up @@ -3789,13 +3855,35 @@ exports[`validate-message.jsx 1`] = `
class="t-input__wrap"
>
<div
class="t-input"
class="t-input t-input--suffix"
>
<input
class="t-input__inner"
type="password"
value=""
/>
<span
class="t-input__suffix t-input__suffix-icon"
>
<svg
class="t-icon t-icon-browse-off t-input__suffix-clear"
fill="none"
height="1em"
viewBox="0 0 16 16"
width="1em"
>
<path
d="M10.77 11.98l1.38 1.37.7-.7-9.7-9.7-.7.7 1.2 1.21a7.9 7.9 0 00-2.53 2.91L1 8l.12.23a7.72 7.72 0 009.65 3.75zM10 11.2A6.67 6.67 0 012.11 8c.56-1 1.34-1.83 2.26-2.43l1.08 1.09a2.88 2.88 0 003.9 3.9l.64.64zM6.21 7.42l2.37 2.37a1.88 1.88 0 01-2.37-2.37zM14.88 8.23L15 8l-.12-.23a7.73 7.73 0 00-9.35-3.86l.8.8A6.7 6.7 0 0113.9 8a6.87 6.87 0 01-2.02 2.26l.7.7a7.9 7.9 0 002.3-2.73z"
fill="currentColor"
fill-opacity="0.9"
/>
<path
d="M10.88 8c0 .37-.07.73-.2 1.06l-.82-.82.02-.24a1.88 1.88 0 00-2.12-1.86l-.82-.82A2.87 2.87 0 0110.88 8z"
fill="currentColor"
fill-opacity="0.9"
/>
</svg>
</span>
</div>
</div>
</div>
Expand Down
52 changes: 28 additions & 24 deletions src/input/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState, useRef, useImperativeHandle, useEffect } from 'react';
import classNames from 'classnames';
import { CloseCircleFilledIcon } from 'tdesign-icons-react';
import { CloseCircleFilledIcon, BrowseOffIcon, BrowseIcon } from 'tdesign-icons-react';
import isFunction from 'lodash/isFunction';
import forwardRefWithStatics from '../_util/forwardRefWithStatics';
import useConfig from '../_util/useConfig';
Expand All @@ -27,7 +27,7 @@ const renderIcon = (classPrefix: string, type: 'prefix' | 'suffix', icon: TNode)

if (typeof icon === 'function') result = icon();

const iconClassName = icon ? `${classPrefix}-input__suffix-icon` : '';
const iconClassName = icon ? `${classPrefix}-input__${type}-icon` : '';

if (result) {
result = <span className={`${classPrefix}-input__${type} ${iconClassName}`}>{result}</span>;
Expand All @@ -39,6 +39,7 @@ const renderIcon = (classPrefix: string, type: 'prefix' | 'suffix', icon: TNode)
const Input = forwardRefWithStatics(
(props: InputProps, ref) => {
const {
type,
autoWidth,
placeholder,
disabled,
Expand Down Expand Up @@ -87,32 +88,30 @@ const Input = forwardRefWithStatics(
const wrapperRef: React.RefObject<HTMLDivElement> = useRef();
const [isHover, toggleIsHover] = useState(false);
const [isFocused, toggleIsFocused] = useState(false);
const [renderType, setRenderType] = useState(type);

const [composingRefValue, setComposingValue] = useState<string>('');
const isShowClearIcon = ((clearable && value && !disabled) || showClearIconOnEmpty) && isHover;

const prefixIconContent = renderIcon(classPrefix, 'prefix', prefixIcon);
const suffixIconNew = isShowClearIcon ? (
<CloseCircleFilledIcon className={`${classPrefix}-input__suffix-clear`} onClick={handleClear} />
) : (
suffixIcon
);
let suffixIconNew = suffixIcon;

if (isShowClearIcon)
suffixIconNew = <CloseCircleFilledIcon className={`${classPrefix}-input__suffix-clear`} onClick={handleClear} />;
if (type === 'password') {
if (renderType === 'password') {
suffixIconNew = (
<BrowseOffIcon className={`${classPrefix}-input__suffix-clear`} onClick={togglePasswordVisible} />
);
} else if (renderType === 'text') {
suffixIconNew = <BrowseIcon className={`${classPrefix}-input__suffix-clear`} onClick={togglePasswordVisible} />;
}
}

const suffixIconContent = renderIcon(classPrefix, 'suffix', suffixIconNew);
const labelContent = isFunction(label) ? label() : label;
const suffixContent = isFunction(suffix) ? suffix() : suffix;

const inputPropsNames = Object.keys(restProps).filter((key) => !/^on[A-Z]/.test(key));
const inputProps = inputPropsNames.reduce((inputProps, key) => Object.assign(inputProps, { [key]: props[key] }), {
className: '',
});
const eventPropsNames = Object.keys(restProps).filter((key) => /^on[A-Z]/.test(key));
const eventProps = eventPropsNames.reduce((eventProps, key) => {
Object.assign(eventProps, {
[key]: (e: any) => props[key](e.currentTarget.value, { e }),
});
return eventProps;
}, {});

useEffect(() => {
if (!autoWidth) return;
inputRef.current.style.width = `${inputPreRef.current.offsetWidth}px`;
Expand All @@ -122,9 +121,8 @@ const Input = forwardRefWithStatics(
<input
ref={inputRef}
placeholder={placeholder}
{...inputProps}
{...eventProps}
className={classNames(inputProps.className, `${classPrefix}-input__inner`)}
type={renderType}
className={`${classPrefix}-input__inner`}
value={composingRef.current ? composingRefValue : value}
readOnly={readonly}
disabled={disabled}
Expand All @@ -145,7 +143,7 @@ const Input = forwardRefWithStatics(

const renderInputNode = (
<div
className={classNames(`${classPrefix}-input`, {
className={classNames(className, `${classPrefix}-input`, {
[`${classPrefix}-is-readonly`]: readonly,
[`${classPrefix}-is-disabled`]: disabled,
[`${classPrefix}-is-focused`]: isFocused,
Expand Down Expand Up @@ -175,6 +173,11 @@ const Input = forwardRefWithStatics(
</div>
);

function togglePasswordVisible() {
const toggleType = renderType === 'password' ? 'text' : 'password';
setRenderType(toggleType);
}

function handleChange(e: React.ChangeEvent<HTMLInputElement> | React.CompositionEvent<HTMLInputElement>) {
let { value } = e.currentTarget;
if (composingRef.current) {
Expand Down Expand Up @@ -279,9 +282,10 @@ const Input = forwardRefWithStatics(
<div
ref={wrapperRef}
style={style}
className={classNames(className, `${classPrefix}-input__wrap`, {
className={classNames(`${classPrefix}-input__wrap`, {
[`${classPrefix}-input--auto-width`]: autoWidth,
})}
{...restProps}
>
{renderInputNode}
{tips && (
Expand Down
6 changes: 3 additions & 3 deletions src/input/InputGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ export interface InputGroupProps extends React.HTMLAttributes<HTMLDivElement> {
* 是否拆分
* @default false
*/
seperate?: boolean;
separate?: boolean;
}

const InputGroup = forwardRef((props: InputGroupProps, ref: React.Ref<HTMLDivElement>) => {
const { classPrefix } = useConfig();
const { seperate, children, className, ...wrapperProps } = props;
const { separate, children, className, ...wrapperProps } = props;
return (
<div
ref={ref}
className={classNames(className, `${classPrefix}-input-group`, {
[`${classPrefix}-input-group--seperate`]: seperate,
[`${classPrefix}-input-group--separate`]: separate,
})}
{...wrapperProps}
>
Expand Down
Loading

0 comments on commit 87b48e3

Please sign in to comment.