Skip to content

Commit 89323bd

Browse files
authored
feat: BaseInput support components (#41)
1 parent 4dbc785 commit 89323bd

File tree

4 files changed

+85
-9
lines changed

4 files changed

+85
-9
lines changed

src/BaseInput.tsx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,15 @@ const BaseInput: FC<BaseInputProps> = (props) => {
2626
classNames,
2727
dataAttrs,
2828
styles,
29+
components,
2930
} = props;
3031

31-
const containerRef = useRef<HTMLSpanElement>(null);
32+
const AffixWrapperComponent = components?.affixWrapper || 'span';
33+
const GroupWrapperComponent = components?.groupWrapper || 'span';
34+
const WrapperComponent = components?.wrapper || 'span';
35+
const GroupAddonComponent = components?.groupAddon || 'span';
36+
37+
const containerRef = useRef<HTMLDivElement>(null);
3238

3339
const onInputClick: React.MouseEventHandler = (e) => {
3440
if (containerRef.current?.contains(e.target as Element)) {
@@ -94,6 +100,7 @@ const BaseInput: FC<BaseInputProps> = (props) => {
94100
},
95101
!hasAddon(props) && className,
96102
classes?.affixWrapper,
103+
classNames?.affixWrapper,
97104
);
98105

99106
const suffixNode = (suffix || allowClear) && (
@@ -107,7 +114,7 @@ const BaseInput: FC<BaseInputProps> = (props) => {
107114
);
108115

109116
element = (
110-
<span
117+
<AffixWrapperComponent
111118
className={affixWrapperCls}
112119
style={!hasAddon(props) ? style : undefined}
113120
hidden={!hasAddon(props) && hidden}
@@ -128,7 +135,7 @@ const BaseInput: FC<BaseInputProps> = (props) => {
128135
hidden: null,
129136
})}
130137
{suffixNode}
131-
</span>
138+
</AffixWrapperComponent>
132139
);
133140
}
134141

@@ -152,15 +159,27 @@ const BaseInput: FC<BaseInputProps> = (props) => {
152159
// Need another wrapper for changing display:table to display:inline-block
153160
// and put style prop in wrapper
154161
return (
155-
<span className={mergedGroupClassName} style={style} hidden={hidden}>
156-
<span className={mergedWrapperClassName}>
157-
{addonBefore && <span className={addonCls}>{addonBefore}</span>}
162+
<GroupWrapperComponent
163+
className={mergedGroupClassName}
164+
style={style}
165+
hidden={hidden}
166+
>
167+
<WrapperComponent className={mergedWrapperClassName}>
168+
{addonBefore && (
169+
<GroupAddonComponent className={addonCls}>
170+
{addonBefore}
171+
</GroupAddonComponent>
172+
)}
158173
{cloneElement(element, {
159174
hidden: null,
160175
})}
161-
{addonAfter && <span className={addonCls}>{addonAfter}</span>}
162-
</span>
163-
</span>
176+
{addonAfter && (
177+
<GroupAddonComponent className={addonCls}>
178+
{addonAfter}
179+
</GroupAddonComponent>
180+
)}
181+
</WrapperComponent>
182+
</GroupWrapperComponent>
164183
);
165184
}
166185
return element;

src/interface.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ export interface CommonInputProps {
1414
suffix?: ReactNode;
1515
addonBefore?: ReactNode;
1616
addonAfter?: ReactNode;
17+
/** @deprecated Use `classNames` instead */
1718
classes?: {
1819
affixWrapper?: string;
1920
group?: string;
2021
wrapper?: string;
2122
};
2223
classNames?: {
24+
affixWrapper?: string;
2325
prefix?: string;
2426
suffix?: string;
2527
};
2628
styles?: {
29+
affixWrapper?: CSSProperties;
2730
prefix?: CSSProperties;
2831
suffix?: CSSProperties;
2932
};
@@ -47,6 +50,12 @@ export interface BaseInputProps extends CommonInputProps {
4750
dataAttrs?: {
4851
affixWrapper?: DataAttr;
4952
};
53+
components?: {
54+
affixWrapper?: 'span' | 'div';
55+
groupWrapper?: 'span' | 'div';
56+
wrapper?: 'span' | 'div';
57+
groupAddon?: 'span' | 'div';
58+
};
5059
}
5160

5261
export interface ShowCountProps {

tests/BaseInput.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,22 @@ describe('BaseInput', () => {
190190
);
191191
expect(container).toMatchSnapshot();
192192
});
193+
194+
it('support use div as basic element', () => {
195+
const { container } = render(
196+
<BaseInput
197+
prefixCls="rc-input"
198+
prefix="prefix"
199+
addonBefore="addon"
200+
inputElement={<input />}
201+
components={{
202+
affixWrapper: 'div',
203+
groupWrapper: 'div',
204+
wrapper: 'div',
205+
groupAddon: 'div',
206+
}}
207+
/>,
208+
);
209+
expect(container).toMatchSnapshot();
210+
});
193211
});

tests/__snapshots__/BaseInput.test.tsx.snap

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,33 @@ exports[`BaseInput should render perfectly 1`] = `
111111
/>
112112
</div>
113113
`;
114+
115+
exports[`BaseInput support use div as basic element 1`] = `
116+
<div>
117+
<div
118+
class="rc-input-group-wrapper"
119+
>
120+
<div
121+
class="rc-input-wrapper rc-input-group"
122+
>
123+
<div
124+
class="rc-input-group-addon"
125+
>
126+
addon
127+
</div>
128+
<div
129+
class="rc-input-affix-wrapper"
130+
>
131+
<span
132+
class="rc-input-prefix"
133+
>
134+
prefix
135+
</span>
136+
<input
137+
value=""
138+
/>
139+
</div>
140+
</div>
141+
</div>
142+
</div>
143+
`;

0 commit comments

Comments
 (0)