From bb96acb255c6a610a78a0ec5704c2f96d06a35f0 Mon Sep 17 00:00:00 2001 From: MadCcc <1075746765@qq.com> Date: Mon, 27 Mar 2023 21:47:00 +0800 Subject: [PATCH] feat: support classNames and styles (#38) --- src/BaseInput.tsx | 38 ++++++++++---------- src/Input.tsx | 32 ++++++++++------- src/interface.ts | 26 ++++++++------ tests/BaseInput.test.tsx | 25 ------------- tests/__snapshots__/BaseInput.test.tsx.snap | 39 --------------------- tests/__snapshots__/index.test.tsx.snap | 33 +++++++++++++++++ tests/index.test.tsx | 31 ++++++++++++++-- 7 files changed, 116 insertions(+), 108 deletions(-) diff --git a/src/BaseInput.tsx b/src/BaseInput.tsx index 87e4d9e..0106bd8 100644 --- a/src/BaseInput.tsx +++ b/src/BaseInput.tsx @@ -1,4 +1,4 @@ -import classNames from 'classnames'; +import clsx from 'classnames'; import type { FC, ReactElement } from 'react'; import React, { cloneElement, useRef } from 'react'; import type { BaseInputProps } from './interface'; @@ -14,9 +14,6 @@ const BaseInput: FC = (props) => { addonAfter, className, style, - affixWrapperClassName, - groupClassName, - wrapperClassName, disabled, readOnly, focused, @@ -25,9 +22,10 @@ const BaseInput: FC = (props) => { value, handleReset, hidden, - inputStyle, classes, + classNames, dataAttrs, + styles, } = props; const containerRef = useRef(null); @@ -56,7 +54,7 @@ const BaseInput: FC = (props) => { // Do not trigger onBlur when clear input // https://github.com/ant-design/ant-design/issues/31200 onMouseDown={(e) => e.preventDefault()} - className={classNames(clearIconCls, { + className={clsx(clearIconCls, { [`${clearIconCls}-hidden`]: !needClear, [`${clearIconCls}-has-suffix`]: !!suffix, })} @@ -72,20 +70,19 @@ const BaseInput: FC = (props) => { value, hidden, className: - classNames( + clsx( inputElement.props?.className, !hasPrefixSuffix(props) && !hasAddon(props) && className, ) || null, style: { ...inputElement.props?.style, - ...inputStyle, }, }); // ================== Prefix & Suffix ================== // if (hasPrefixSuffix(props)) { const affixWrapperPrefixCls = `${prefixCls}-affix-wrapper`; - const affixWrapperCls = classNames( + const affixWrapperCls = clsx( affixWrapperPrefixCls, { [`${affixWrapperPrefixCls}-disabled`]: disabled, @@ -95,12 +92,14 @@ const BaseInput: FC = (props) => { suffix && allowClear && value, }, !hasAddon(props) && className, - affixWrapperClassName, classes?.affixWrapper, ); const suffixNode = (suffix || allowClear) && ( - + {getClearIcon()} {suffix} @@ -115,9 +114,15 @@ const BaseInput: FC = (props) => { {...dataAttrs?.affixWrapper} ref={containerRef} > - {prefix && {prefix}} + {prefix && ( + + {prefix} + + )} {cloneElement(inputElement, { - style: inputStyle ?? null, value, hidden: null, })} @@ -131,17 +136,15 @@ const BaseInput: FC = (props) => { const wrapperCls = `${prefixCls}-group`; const addonCls = `${wrapperCls}-addon`; - const mergedWrapperClassName = classNames( + const mergedWrapperClassName = clsx( `${prefixCls}-wrapper`, wrapperCls, - wrapperClassName, classes?.wrapper, ); - const mergedGroupClassName = classNames( + const mergedGroupClassName = clsx( `${prefixCls}-group-wrapper`, className, - groupClassName, classes?.group, ); @@ -152,7 +155,6 @@ const BaseInput: FC = (props) => { {addonBefore && {addonBefore}} {cloneElement(element, { - style: inputStyle ?? null, hidden: null, })} {addonAfter && {addonAfter}} diff --git a/src/Input.tsx b/src/Input.tsx index 3edcf67..075ae05 100644 --- a/src/Input.tsx +++ b/src/Input.tsx @@ -1,4 +1,4 @@ -import classNames from 'classnames'; +import clsx from 'classnames'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import omit from 'rc-util/lib/omit'; import React, { @@ -33,8 +33,9 @@ const Input = forwardRef((props, ref) => { suffix, showCount, type = 'text', - inputClassName, classes, + classNames, + styles, ...rest } = props; @@ -121,12 +122,10 @@ const Input = forwardRef((props, ref) => { // specify either the value prop, or the defaultValue prop, but not both. 'defaultValue', 'showCount', - 'affixWrapperClassName', - 'groupClassName', - 'inputClassName', 'classes', - 'wrapperClassName', 'htmlSize', + 'styles', + 'classNames', ]); return ( ((props, ref) => { onFocus={handleFocus} onBlur={handleBlur} onKeyDown={handleKeyDown} - className={classNames( + className={clsx( prefixCls, { [`${prefixCls}-disabled`]: disabled, }, - inputClassName, - classes?.input, + classNames?.input, )} + style={styles?.input} ref={inputRef} size={htmlSize} type={type} @@ -167,9 +166,16 @@ const Input = forwardRef((props, ref) => { <> {!!showCount && ( {dataCount} @@ -194,6 +200,8 @@ const Input = forwardRef((props, ref) => { suffix={getSuffix()} disabled={disabled} classes={classes} + classNames={classNames} + styles={styles} /> ); }); diff --git a/src/interface.ts b/src/interface.ts index 761ebfb..3727420 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -6,8 +6,8 @@ import type { ReactElement, ReactNode, } from 'react'; -import type { LiteralUnion } from './utils/types'; import type { InputFocusOptions } from './utils/commonUtils'; +import type { LiteralUnion } from './utils/types'; export interface CommonInputProps { prefix?: ReactNode; @@ -19,12 +19,14 @@ export interface CommonInputProps { group?: string; wrapper?: string; }; - /** @deprecated Use classes instead */ - affixWrapperClassName?: string; - /** @deprecated Use classes instead */ - groupClassName?: string; - /** @deprecated Use classes instead */ - wrapperClassName?: string; + classNames?: { + prefix?: string; + suffix?: string; + }; + styles?: { + prefix?: CSSProperties; + suffix?: CSSProperties; + }; allowClear?: boolean | { clearIcon?: ReactNode }; } @@ -42,7 +44,6 @@ export interface BaseInputProps extends CommonInputProps { readOnly?: boolean; handleReset?: MouseEventHandler; hidden?: boolean; - inputStyle?: CSSProperties; dataAttrs?: { affixWrapper?: DataAttr; }; @@ -90,10 +91,13 @@ export interface InputProps showCount?: boolean | ShowCountProps; autoComplete?: string; htmlSize?: number; - /** @deprecated Use classes instead */ - inputClassName?: string; - classes?: CommonInputProps['classes'] & { + classNames?: CommonInputProps['classNames'] & { input?: string; + count?: string; + }; + styles?: CommonInputProps['styles'] & { + input?: CSSProperties; + count?: CSSProperties; }; } diff --git a/tests/BaseInput.test.tsx b/tests/BaseInput.test.tsx index 665d1a7..e5121fa 100644 --- a/tests/BaseInput.test.tsx +++ b/tests/BaseInput.test.tsx @@ -130,31 +130,6 @@ describe('BaseInput', () => { expect(document.activeElement).toBe(container.querySelector('input')); }); - it('should support inputStyle', () => { - const { container } = render( - <> - } - /> - } - /> - } - /> - , - ); - expect(container).toMatchSnapshot(); - }); - it('should support data-*', () => { const { container } = render( `; - -exports[`BaseInput should support inputStyle 1`] = ` -
- - - - prefix - - - - - - - addon - - - - -
-`; diff --git a/tests/__snapshots__/index.test.tsx.snap b/tests/__snapshots__/index.test.tsx.snap index e60e247..856cdf3 100644 --- a/tests/__snapshots__/index.test.tsx.snap +++ b/tests/__snapshots__/index.test.tsx.snap @@ -1,5 +1,38 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Input allowClear classNames and styles should work 1`] = ` +
+ + + prefix + + + + + 3 + + suffix + + +
+`; + exports[`Input allowClear should change type when click 1`] = `
{ @@ -239,6 +239,31 @@ describe('Input allowClear', () => { ).toBeTruthy(); }); }); + + it('classNames and styles should work', () => { + const { container } = render( + , + ); + expect(container).toMatchSnapshot(); + }); }); describe('Input ref', () => {