Skip to content

Commit

Permalink
Pass through FormControl.Label props (#3262)
Browse files Browse the repository at this point in the history
* add test

* changeset

* pass through InputLabel props too
  • Loading branch information
mattcosta7 authored May 8, 2023
1 parent 3d89d51 commit 7f2ddce
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/polite-chicken-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

passthrough form control label props
44 changes: 29 additions & 15 deletions src/FormControl/_FormControlLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import InputLabel, {LabelProps, LegendOrSpanProps} from '../_InputLabel'
import InputLabel from '../_InputLabel'
import {SxProp} from '../sx'
import {FormControlContext} from './FormControl'

Expand All @@ -12,21 +12,35 @@ export type Props = {
} & SxProp

const FormControlLabel: React.FC<
React.PropsWithChildren<{htmlFor?: string} & (LegendOrSpanProps | LabelProps) & Props>
> = ({children, htmlFor, id, visuallyHidden, sx}) => {
React.PropsWithChildren<{htmlFor?: string} & React.ComponentProps<typeof InputLabel> & Props>
> = ({as, children, htmlFor, id, visuallyHidden, sx, ...props}) => {
const {disabled, id: formControlId, required} = React.useContext(FormControlContext)
return (
<InputLabel
htmlFor={htmlFor || formControlId}
id={id}
visuallyHidden={visuallyHidden}
required={required}
disabled={disabled}
sx={sx}
>
{children}
</InputLabel>
)

/**
* Ensure we can pass through props correctly, since legend/span accept no defined 'htmlFor'
*/
const labelProps: React.ComponentProps<typeof InputLabel> =
as === 'legend' || as === 'span'
? {
as,
id,
visuallyHidden,
required,
disabled,
sx,
...props,
}
: {
as,
id,
visuallyHidden,
htmlFor: htmlFor || formControlId,
required,
disabled,
sx,
...props,
}
return <InputLabel {...labelProps}>{children}</InputLabel>
}

export default FormControlLabel
2 changes: 2 additions & 0 deletions src/_InputLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const InputLabel: React.FC<React.PropsWithChildren<Props>> = ({
visuallyHidden,
sx,
as = 'label',
...props
}) => {
return (
<VisuallyHidden
Expand All @@ -49,6 +50,7 @@ const InputLabel: React.FC<React.PropsWithChildren<Props>> = ({
alignSelf: 'flex-start',
...sx,
}}
{...props}
>
{required ? (
<Box display="flex" as="span">
Expand Down
18 changes: 18 additions & 0 deletions src/__tests__/FormControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,24 @@ describe('FormControl', () => {
expect(input).toBeDefined()
expect(label).toBeDefined()
})

it('passes through props on the label element', () => {
const {getByLabelText, getByText} = render(
<SSRProvider>
<FormControl>
<FormControl.Label data-testid="some-test-id">{LABEL_TEXT}</FormControl.Label>
<Textarea />
</FormControl>
</SSRProvider>,
)

const input = getByLabelText(LABEL_TEXT)
const label = getByText(LABEL_TEXT)

expect(input).toBeDefined()
expect(label).toBeDefined()
expect(label).toHaveAttribute('data-testid', 'some-test-id')
})
})

describe('ARIA attributes', () => {
Expand Down

0 comments on commit 7f2ddce

Please sign in to comment.