Skip to content

Commit

Permalink
feat: support classNames and styles (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
MadCcc authored Mar 27, 2023
1 parent d17633e commit bb96acb
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 108 deletions.
38 changes: 20 additions & 18 deletions src/BaseInput.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -14,9 +14,6 @@ const BaseInput: FC<BaseInputProps> = (props) => {
addonAfter,
className,
style,
affixWrapperClassName,
groupClassName,
wrapperClassName,
disabled,
readOnly,
focused,
Expand All @@ -25,9 +22,10 @@ const BaseInput: FC<BaseInputProps> = (props) => {
value,
handleReset,
hidden,
inputStyle,
classes,
classNames,
dataAttrs,
styles,
} = props;

const containerRef = useRef<HTMLSpanElement>(null);
Expand Down Expand Up @@ -56,7 +54,7 @@ const BaseInput: FC<BaseInputProps> = (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,
})}
Expand All @@ -72,20 +70,19 @@ const BaseInput: FC<BaseInputProps> = (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,
Expand All @@ -95,12 +92,14 @@ const BaseInput: FC<BaseInputProps> = (props) => {
suffix && allowClear && value,
},
!hasAddon(props) && className,
affixWrapperClassName,
classes?.affixWrapper,
);

const suffixNode = (suffix || allowClear) && (
<span className={`${prefixCls}-suffix`}>
<span
className={clsx(`${prefixCls}-suffix`, classNames?.suffix)}
style={styles?.suffix}
>
{getClearIcon()}
{suffix}
</span>
Expand All @@ -115,9 +114,15 @@ const BaseInput: FC<BaseInputProps> = (props) => {
{...dataAttrs?.affixWrapper}
ref={containerRef}
>
{prefix && <span className={`${prefixCls}-prefix`}>{prefix}</span>}
{prefix && (
<span
className={clsx(`${prefixCls}-prefix`, classNames?.prefix)}
style={styles?.prefix}
>
{prefix}
</span>
)}
{cloneElement(inputElement, {
style: inputStyle ?? null,
value,
hidden: null,
})}
Expand All @@ -131,17 +136,15 @@ const BaseInput: FC<BaseInputProps> = (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,
);

Expand All @@ -152,7 +155,6 @@ const BaseInput: FC<BaseInputProps> = (props) => {
<span className={mergedWrapperClassName}>
{addonBefore && <span className={addonCls}>{addonBefore}</span>}
{cloneElement(element, {
style: inputStyle ?? null,
hidden: null,
})}
{addonAfter && <span className={addonCls}>{addonAfter}</span>}
Expand Down
32 changes: 20 additions & 12 deletions src/Input.tsx
Original file line number Diff line number Diff line change
@@ -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, {
Expand Down Expand Up @@ -33,8 +33,9 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
suffix,
showCount,
type = 'text',
inputClassName,
classes,
classNames,
styles,
...rest
} = props;

Expand Down Expand Up @@ -121,12 +122,10 @@ const Input = forwardRef<InputRef, InputProps>((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 (
<input
Expand All @@ -136,14 +135,14 @@ const Input = forwardRef<InputRef, InputProps>((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}
Expand All @@ -167,9 +166,16 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
<>
{!!showCount && (
<span
className={classNames(`${prefixCls}-show-count-suffix`, {
[`${prefixCls}-show-count-has-suffix`]: !!suffix,
})}
className={clsx(
`${prefixCls}-show-count-suffix`,
{
[`${prefixCls}-show-count-has-suffix`]: !!suffix,
},
classNames?.count,
)}
style={{
...styles?.count,
}}
>
{dataCount}
</span>
Expand All @@ -194,6 +200,8 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
suffix={getSuffix()}
disabled={disabled}
classes={classes}
classNames={classNames}
styles={styles}
/>
);
});
Expand Down
26 changes: 15 additions & 11 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 };
}

Expand All @@ -42,7 +44,6 @@ export interface BaseInputProps extends CommonInputProps {
readOnly?: boolean;
handleReset?: MouseEventHandler;
hidden?: boolean;
inputStyle?: CSSProperties;
dataAttrs?: {
affixWrapper?: DataAttr;
};
Expand Down Expand Up @@ -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;
};
}

Expand Down
25 changes: 0 additions & 25 deletions tests/BaseInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,31 +130,6 @@ describe('BaseInput', () => {
expect(document.activeElement).toBe(container.querySelector('input'));
});

it('should support inputStyle', () => {
const { container } = render(
<>
<BaseInput
prefixCls="rc-input"
inputStyle={{ marginTop: 200 }}
inputElement={<input style={{ marginLeft: 100 }} />}
/>
<BaseInput
prefixCls="rc-input"
prefix="prefix"
inputStyle={{ marginTop: 200 }}
inputElement={<input style={{ marginLeft: 100 }} />}
/>
<BaseInput
prefixCls="rc-input"
addonBefore="addon"
inputStyle={{ marginTop: 200 }}
inputElement={<input style={{ marginLeft: 100 }} />}
/>
</>,
);
expect(container).toMatchSnapshot();
});

it('should support data-*', () => {
const { container } = render(
<BaseInput
Expand Down
39 changes: 0 additions & 39 deletions tests/__snapshots__/BaseInput.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -111,42 +111,3 @@ exports[`BaseInput should render perfectly 1`] = `
/>
</div>
`;

exports[`BaseInput should support inputStyle 1`] = `
<div>
<input
style="margin-left: 100px; margin-top: 200px;"
value=""
/>
<span
class="rc-input-affix-wrapper"
>
<span
class="rc-input-prefix"
>
prefix
</span>
<input
style="margin-top: 200px;"
value=""
/>
</span>
<span
class="rc-input-group-wrapper"
>
<span
class="rc-input-wrapper rc-input-group"
>
<span
class="rc-input-group-addon"
>
addon
</span>
<input
style="margin-top: 200px;"
value=""
/>
</span>
</span>
</div>
`;
33 changes: 33 additions & 0 deletions tests/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Input allowClear classNames and styles should work 1`] = `
<div>
<span
class="rc-input-affix-wrapper"
>
<span
class="rc-input-prefix custom-prefix"
style="color: blue;"
>
prefix
</span>
<input
class="rc-input custom-input"
style="color: red;"
type="text"
value="123"
/>
<span
class="rc-input-suffix custom-suffix"
style="color: yellow;"
>
<span
class="rc-input-show-count-suffix rc-input-show-count-has-suffix custom-count"
style="color: green;"
>
3
</span>
suffix
</span>
</span>
</div>
`;

exports[`Input allowClear should change type when click 1`] = `
<div>
<span
Expand Down
Loading

0 comments on commit bb96acb

Please sign in to comment.