Skip to content

Commit 8be7f3b

Browse files
authored
Simplify the Input element type (#2306)
1 parent f583d05 commit 8be7f3b

19 files changed

+79
-95
lines changed

.changeset/flat-steaks-itch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sumup-oss/circuit-ui': major
3+
---
4+
5+
Deprecated the `InputElement` interface and narrowed the Input's element type to `HTMLInputElement` and the TextArea's element type to `HTMLTextAreaElement`. This affects `ref`s and event handlers.

packages/circuit-ui/components/CurrencyInput/CurrencyInput.spec.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { describe, expect, it } from 'vitest';
1717
import { createRef, useState, type ChangeEvent } from 'react';
1818

1919
import { render, userEvent, axe, screen } from '../../util/test-utils.js';
20-
import type { InputElement } from '../Input/index.js';
2120

2221
import { CurrencyInput, type CurrencyInputProps } from './CurrencyInput.js';
2322

@@ -30,7 +29,7 @@ const defaultProps = {
3029

3130
describe('CurrencyInput', () => {
3231
it('should forward a ref', () => {
33-
const ref = createRef<InputElement>();
32+
const ref = createRef<HTMLInputElement>();
3433
render(<CurrencyInput {...defaultProps} ref={ref} />);
3534
const input: HTMLInputElement = screen.getByRole('textbox');
3635
expect(ref.current).toBe(input);

packages/circuit-ui/components/CurrencyInput/CurrencyInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { resolveCurrencyFormat } from '@sumup-oss/intl';
2020
import { NumericFormat, type NumericFormatProps } from 'react-number-format';
2121

2222
import { clsx } from '../../styles/clsx.js';
23-
import { Input, type InputElement, type InputProps } from '../Input/index.js';
23+
import { Input, type InputProps } from '../Input/index.js';
2424

2525
import { formatPlaceholder } from './CurrencyInputService.js';
2626
import classes from './CurrencyInput.module.css';
@@ -73,7 +73,7 @@ const DUMMY_DELIMITER = '?';
7373
* the symbol according to the locale. The corresponding service exports a
7474
* parser for formatting values automatically.
7575
*/
76-
export const CurrencyInput = forwardRef<InputElement, CurrencyInputProps>(
76+
export const CurrencyInput = forwardRef<HTMLInputElement, CurrencyInputProps>(
7777
(
7878
{
7979
locale,

packages/circuit-ui/components/DateInput/DateInput.spec.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@ import { describe, expect, it } from 'vitest';
1717
import { createRef } from 'react';
1818

1919
import { render, axe } from '../../util/test-utils.js';
20-
import type { InputElement } from '../Input/index.js';
2120

2221
import { DateInput } from './DateInput.js';
2322

2423
describe('DateInput', () => {
2524
const baseProps = { label: 'Date' };
2625

2726
it('should forward a ref', () => {
28-
const ref = createRef<InputElement>();
27+
const ref = createRef<HTMLInputElement>();
2928
const { container } = render(<DateInput {...baseProps} ref={ref} />);
3029
const input = container.querySelector('input');
3130
expect(ref.current).toBe(input);

packages/circuit-ui/components/DateInput/DateInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import { forwardRef, useState, useEffect } from 'react';
1919
import { PatternFormat } from 'react-number-format';
2020

21-
import { Input, type InputElement, type InputProps } from '../Input/index.js';
21+
import { Input, type InputProps } from '../Input/index.js';
2222
import { clsx } from '../../styles/clsx.js';
2323

2424
import classes from './DateInput.module.css';
@@ -42,7 +42,7 @@ export interface DateInputProps
4242
* DateInput component for forms.
4343
* The input value is always a string in the format `YYYY-MM-DD`.
4444
*/
45-
export const DateInput = forwardRef<InputElement, DateInputProps>(
45+
export const DateInput = forwardRef<HTMLInputElement, DateInputProps>(
4646
({ inputClassName, ...props }, ref) => {
4747
// When server-side rendering, we assume that the user's browser supports
4848
// the native date input.

packages/circuit-ui/components/Input/Input.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { createRef } from 'react';
1818

1919
import { render, axe, screen } from '../../util/test-utils.js';
2020

21-
import { Input, type InputElement } from './Input.js';
21+
import { Input } from './Input.js';
2222

2323
const defaultProps = {
2424
label: 'Label',
@@ -35,14 +35,14 @@ describe('Input', () => {
3535
});
3636

3737
it('should forward a ref to the input', () => {
38-
const ref = createRef<InputElement>();
38+
const ref = createRef<HTMLInputElement>();
3939
const { container } = render(<Input ref={ref} {...defaultProps} />);
4040
const input = container.querySelector('input');
4141
expect(ref.current).toBe(input);
4242
});
4343

4444
it('should forward a ref to the textarea', () => {
45-
const ref = createRef<InputElement>();
45+
const ref = createRef<HTMLInputElement>();
4646
const { container } = render(
4747
<Input as="textarea" ref={ref} {...defaultProps} />,
4848
);

packages/circuit-ui/components/Input/Input.tsx

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
useId,
2121
type ComponentType,
2222
type InputHTMLAttributes,
23-
type TextareaHTMLAttributes,
2423
} from 'react';
2524

2625
import {
@@ -38,19 +37,18 @@ import { clsx } from '../../styles/clsx.js';
3837

3938
import classes from './Input.module.css';
4039

41-
export type InputElement = HTMLInputElement & HTMLTextAreaElement;
42-
type CircuitInputHTMLAttributes = InputHTMLAttributes<HTMLInputElement> &
43-
TextareaHTMLAttributes<HTMLTextAreaElement>;
40+
/**
41+
* @deprecated
42+
*
43+
* Use the `HTMLInputElement` or `HTMLTextAreaElement` interfaces instead.
44+
*/
45+
export type InputElement = HTMLInputElement;
4446

45-
export interface InputProps extends CircuitInputHTMLAttributes {
47+
export interface BaseInputProps {
4648
/**
4749
* A clear and concise description of the input purpose.
4850
*/
4951
label: string;
50-
/**
51-
* The HTML input element to render.
52-
*/
53-
as?: 'input' | 'textarea';
5452
/**
5553
* A unique identifier for the input field. If not defined, a randomly
5654
* generated id is used.
@@ -106,10 +104,21 @@ export interface InputProps extends CircuitInputHTMLAttributes {
106104
inputClassName?: string;
107105
}
108106

107+
export interface InputProps
108+
extends BaseInputProps,
109+
InputHTMLAttributes<HTMLInputElement> {
110+
/**
111+
* @private
112+
*
113+
* Use the {@link TextArea} component.
114+
*/
115+
as?: 'input' | 'textarea';
116+
}
117+
109118
/**
110119
* Input component for forms. Takes optional prefix and suffix as render props.
111120
*/
112-
export const Input = forwardRef<InputElement, InputProps>(
121+
export const Input = forwardRef<HTMLInputElement, InputProps>(
113122
(
114123
{
115124
value,
@@ -175,6 +184,9 @@ export const Input = forwardRef<InputElement, InputProps>(
175184
<Element
176185
id={inputId}
177186
value={value}
187+
// @ts-expect-error The Input component renders as an `input` element
188+
// by default. The types are overwritten as necessary in the
189+
// TextArea component.
178190
ref={ref}
179191
aria-describedby={descriptionIds}
180192
className={clsx(

packages/circuit-ui/components/Input/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515

1616
export { Input } from './Input.js';
1717

18-
export type { InputProps, InputElement } from './Input.js';
18+
export type { InputProps, BaseInputProps, InputElement } from './Input.js';

packages/circuit-ui/components/PercentageInput/PercentageInput.spec.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { describe, expect, it } from 'vitest';
1717
import { createRef, useState, type ChangeEvent } from 'react';
1818

1919
import { render, userEvent, axe, screen } from '../../util/test-utils.js';
20-
import type { InputElement } from '../Input/index.js';
2120

2221
import {
2322
PercentageInput,
@@ -31,7 +30,7 @@ const defaultProps = {
3130

3231
describe('PercentageInput', () => {
3332
it('should forward a ref', () => {
34-
const ref = createRef<InputElement>();
33+
const ref = createRef<HTMLInputElement>();
3534
render(<PercentageInput {...defaultProps} ref={ref} />);
3635
const input = screen.getByRole('textbox');
3736
expect(ref.current).toBe(input);

packages/circuit-ui/components/PercentageInput/PercentageInput.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { resolveNumberFormat } from '@sumup-oss/intl';
2020
import { NumericFormat, type NumericFormatProps } from 'react-number-format';
2121

2222
import { clsx } from '../../styles/clsx.js';
23-
import { Input, type InputElement, type InputProps } from '../Input/index.js';
23+
import { Input, type InputProps } from '../Input/index.js';
2424

2525
import { formatPlaceholder } from './PercentageInputService.js';
2626
import classes from './PercentageInput.module.css';
@@ -62,7 +62,10 @@ const DEFAULT_FORMAT = {
6262
/**
6363
* PercentageInput component for fractional values
6464
*/
65-
export const PercentageInput = forwardRef<InputElement, PercentageInputProps>(
65+
export const PercentageInput = forwardRef<
66+
HTMLInputElement,
67+
PercentageInputProps
68+
>(
6669
(
6770
{
6871
locale,

0 commit comments

Comments
 (0)