Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tie field to label without explicit id, and to supporting elements #130

Merged
merged 8 commits into from
Nov 10, 2017
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ exports[`EuiFormRow is rendered 1`] = `
class="euiFormRow testClass1 testClass2"
data-test-subj="test subject string"
>
<input />
<input
id="generated-id"
/>
</div>
`;
25 changes: 22 additions & 3 deletions src/components/form/form_row/form_row.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { EuiFormHelpText } from '../form_help_text';
import { EuiFormErrorText } from '../form_error_text';
import { EuiFormLabel } from '../form_label';

import makeId from './make_id';

export class EuiFormRow extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -40,13 +42,16 @@ export class EuiFormRow extends Component {
isInvalid,
error,
label,
id,
hasEmptyLabelSpace,
fullWidth,
className,
...rest
} = this.props;

const id = rest.id
Copy link
Contributor

Choose a reason for hiding this comment

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

If we make id required, the consumer can use the generator to create an id with a unique suffix.

|| (children && children.props && children.props.id)
|| makeId();

const classes = classNames(
'euiFormRow',
{
Expand All @@ -60,7 +65,7 @@ export class EuiFormRow extends Component {

if (helpText) {
optionalHelpText = (
<EuiFormHelpText className="euiFormRow__text">
<EuiFormHelpText id={makeId()} className="euiFormRow__text">
Copy link
Contributor

Choose a reason for hiding this comment

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

We could then append the string "help" to the id that was provided to create this id.

{helpText}
</EuiFormHelpText>
);
Expand All @@ -71,7 +76,7 @@ export class EuiFormRow extends Component {
if (error) {
const errorTexts = Array.isArray(error) ? error : [error];
optionalErrors = errorTexts.map(error => (
<EuiFormErrorText key={error} className="euiFormRow__text">
<EuiFormErrorText key={error} id={makeId()} className="euiFormRow__text">
Copy link
Contributor

Choose a reason for hiding this comment

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

We could do something similar here by appending "error" and index to create IDs for the errors.

{error}
</EuiFormErrorText>
));
Expand All @@ -91,10 +96,24 @@ export class EuiFormRow extends Component {
);
}

const describingIds = [];
if (optionalHelpText) {
describingIds.push(optionalHelpText.props.id);
}
if (optionalErrors) {
optionalErrors.forEach(error => describingIds.push(error.props.id));
}

const optionalProps = {};
if (describingIds.length > 0) {
optionalProps[`aria-describedby`] = describingIds.join(` `);
}

const field = cloneElement(children, {
id,
onFocus: this.onFocus,
onBlur: this.onBlur,
...optionalProps
});

return (
Expand Down
2 changes: 2 additions & 0 deletions src/components/form/form_row/form_row.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { requiredProps } from '../../../test/required_props';

import { EuiFormRow } from './form_row';

jest.mock(`./make_id`, () => () => `generated-id`);

describe('EuiFormRow', () => {
test('is rendered', () => {
const component = render(
Expand Down
3 changes: 3 additions & 0 deletions src/components/form/form_row/make_id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function makeId() {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about a comment for posterity?

// Generate statistically almost-certainly-unique `id`s for associating form inputs with their labels
// and other descriptive text elements.

return Math.random().toString(36).slice(-8);
}