Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/text-field/text-field.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,17 @@ describe('TextField', () => {
expect(inputElement).toHaveFocus()
})

it('forwards exceptionallySetClassName to the underlying input element', () => {
render(
<TextField
data-testid="text-field"
label="Whatʼs your name?"
exceptionallySetClassName="custom-input-class"
/>,
)
expect(screen.getByTestId('text-field')).toHaveClass('custom-input-class')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Using data-testid may target the field's wrapper instead of the underlying <input> element, which undermines the test's intent to verify exactly where the class lands. To guarantee you are asserting on the input element itself (and to follow the project's testing conventions), query by role instead.

expect(screen.getByRole('textbox', { name: 'Whatʼs your name?' })).toHaveClass('custom-input-class')

You can then safely remove the data-testid prop from the TextField on line 245.

})

describe('a11y', () => {
it('renders with no a11y violations', async () => {
const { container } = render(
Expand Down
6 changes: 5 additions & 1 deletion src/text-field/text-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import { Box } from '../box'
import styles from './text-field.module.css'

import type { BaseFieldProps, BaseFieldVariantProps, FieldComponentProps } from '../base-field'
import type { ObfuscatedClassName } from '../utils/common-types'

type TextFieldType = 'email' | 'search' | 'tel' | 'text' | 'url'

interface TextFieldProps
extends Omit<FieldComponentProps<HTMLInputElement>, 'type' | 'supportsStartAndEndSlots'>,
BaseFieldVariantProps,
Pick<BaseFieldProps, 'characterCountPosition'> {
Pick<BaseFieldProps, 'characterCountPosition'>,
ObfuscatedClassName {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Extending ObfuscatedClassName here makes the public prop docs say this class is applied to the component's main container, but this component now forwards it to the nested input instead. That leaves the TypeScript/IDE contract wrong for both TextField and PasswordField. Define exceptionallySetClassName locally on TextFieldProps with JSDoc that says it targets the underlying input, rather than inheriting the shared root-element type.

type?: TextFieldType
startSlot?: React.ReactElement | string | number
endSlot?: React.ReactElement | string | number
Expand Down Expand Up @@ -45,6 +47,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(function Te
onChange: originalOnChange,
characterCountPosition = 'below',
endSlotPosition = 'bottom',
exceptionallySetClassName,
...props
},
ref,
Expand Down Expand Up @@ -107,6 +110,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(function Te
type={type}
ref={combinedRef}
maxLength={maxLength}
className={exceptionallySetClassName}
onChange={(event) => {
originalOnChange?.(event)
onChange?.(event)
Expand Down
Loading