Skip to content

Commit

Permalink
[EuiSuperDatePicker] Fix multiple IDs regenerating on rerender (#5200)
Browse files Browse the repository at this point in the history
* Fix functional component IDs

* Fix class relativeDateInputNumberDescriptionId

* Fix remaining class IDs

- storing all generated IDs as class vars prevents change on rerender
  • Loading branch information
Constance authored Sep 21, 2021
1 parent 75b18e3 commit 841ed6f
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class EuiRelativeTab extends Component<
sentenceCasedPosition: toSentenceCase(this.props.position),
};

generateId = htmlIdGenerator();
relativeDateInputNumberDescriptionId = htmlIdGenerator()();

onCountChange: ChangeEventHandler<HTMLInputElement> = (event) => {
const sanitizedValue = parseInt(event.target.value, 10);
Expand Down Expand Up @@ -106,7 +106,6 @@ export class EuiRelativeTab extends Component<

render() {
const { count, unit } = this.state;
const relativeDateInputNumberDescriptionId = this.generateId();
const isInvalid = count === undefined || count < 0;
const parsedValue = dateMath.parse(this.props.value, {
roundUp: this.props.roundUp,
Expand Down Expand Up @@ -136,7 +135,7 @@ export class EuiRelativeTab extends Component<
<EuiFieldNumber
compressed
aria-label={numberInputLabel}
aria-describedby={relativeDateInputNumberDescriptionId}
aria-describedby={this.relativeDateInputNumberDescriptionId}
data-test-subj={'superDatePickerRelativeDateInputNumber'}
value={count}
onChange={this.onCountChange}
Expand Down Expand Up @@ -198,7 +197,7 @@ export class EuiRelativeTab extends Component<
}
/>
<EuiScreenReaderOnly>
<p id={relativeDateInputNumberDescriptionId}>
<p id={this.relativeDateInputNumberDescriptionId}>
<EuiI18n
token="euiRelativeTab.fullDescription"
default="The unit is changeable. Currently set to {unit}."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import { EuiFlexGrid, EuiFlexItem } from '../../../flex';
import { EuiTitle } from '../../../title';
import { EuiLink } from '../../../link';
import { EuiHorizontalRule } from '../../../horizontal_rule';
import { htmlIdGenerator } from '../../../../services';
import { useGeneratedHtmlId } from '../../../../services';
import { DurationRange, ApplyTime } from '../../types';

const generateId = htmlIdGenerator();

export interface EuiCommonlyUsedTimeRangesProps {
applyTime: ApplyTime;
commonlyUsedRanges: DurationRange[];
Expand All @@ -26,7 +24,7 @@ export const EuiCommonlyUsedTimeRanges: FunctionComponent<EuiCommonlyUsedTimeRan
applyTime,
commonlyUsedRanges,
}) => {
const legendId = generateId();
const legendId = useGeneratedHtmlId();
const links = commonlyUsedRanges.map(({ start, end, label }) => {
const applyCommonlyUsed = () => {
applyTime({ start, end });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export class EuiQuickSelect extends Component<
}

generateId = htmlIdGenerator();
timeSelectionId = this.generateId();
legendId = this.generateId();

onTimeTenseChange: ChangeEventHandler<HTMLSelectElement> = (event) => {
this.setState({
Expand Down Expand Up @@ -160,8 +162,6 @@ export class EuiQuickSelect extends Component<

render() {
const { timeTense, timeValue, timeUnits } = this.state;
const timeSelectionId = this.generateId();
const legendId = this.generateId();
const matchedTimeUnit = timeUnitsOptions.find(
({ value }) => value === timeUnits
);
Expand All @@ -177,7 +177,7 @@ export class EuiQuickSelect extends Component<
// Legend needs to be the first thing in a fieldset, but we want the visible title within the flex.
// So we hide it, but allow screen readers to see it
<EuiScreenReaderOnly>
<legend id={legendId} className="euiFormLabel">
<legend id={this.legendId} className="euiFormLabel">
{legendText}
</legend>
</EuiScreenReaderOnly>
Expand Down Expand Up @@ -247,7 +247,7 @@ export class EuiQuickSelect extends Component<
compressed
onKeyDown={this.handleKeyDown}
aria-label={tenseLabel}
aria-describedby={`${timeSelectionId} ${legendId}`}
aria-describedby={`${this.timeSelectionId} ${this.legendId}`}
value={timeTense}
options={timeTenseOptions}
onChange={this.onTimeTenseChange}
Expand All @@ -261,7 +261,7 @@ export class EuiQuickSelect extends Component<
<EuiFieldNumber
compressed
onKeyDown={this.handleKeyDown}
aria-describedby={`${timeSelectionId} ${legendId}`}
aria-describedby={`${this.timeSelectionId} ${this.legendId}`}
aria-label={valueLabel}
value={timeValue}
onChange={this.onTimeValueChange}
Expand All @@ -276,7 +276,7 @@ export class EuiQuickSelect extends Component<
compressed
onKeyDown={this.handleKeyDown}
aria-label={unitLabel}
aria-describedby={`${timeSelectionId} ${legendId}`}
aria-describedby={`${this.timeSelectionId} ${this.legendId}`}
value={timeUnits}
options={timeUnitsOptions}
onChange={this.onTimeUnitsChange}
Expand All @@ -286,7 +286,7 @@ export class EuiQuickSelect extends Component<
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
aria-describedby={`${timeSelectionId} ${legendId}`}
aria-describedby={`${this.timeSelectionId} ${this.legendId}`}
className="euiQuickSelect__applyButton"
size="s"
onClick={this.applyQuickSelect}
Expand All @@ -298,7 +298,7 @@ export class EuiQuickSelect extends Component<
</EuiFlexGroup>
<EuiHorizontalRule margin="s" />
<EuiScreenReaderOnly>
<p id={timeSelectionId}>
<p id={this.timeSelectionId}>
<EuiI18n
token="euiQuickSelect.fullDescription"
default="Currently set to {timeTense} {timeValue} {timeUnit}."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import React, { FunctionComponent } from 'react';
import { prettyDuration } from '../pretty_duration';

import { EuiI18n } from '../../../i18n';
import { htmlIdGenerator } from '../../../../services';
import { useGeneratedHtmlId } from '../../../../services';
import { EuiTitle } from '../../../title';
import { EuiLink } from '../../../link';
import { EuiHorizontalRule } from '../../../horizontal_rule';
import { DurationRange, ApplyTime } from '../../types';

const generateId = htmlIdGenerator();

export interface EuiRecentlyUsedProps {
applyTime: ApplyTime;
commonlyUsedRanges: DurationRange[];
Expand All @@ -31,7 +29,7 @@ export const EuiRecentlyUsed: FunctionComponent<EuiRecentlyUsedProps> = ({
dateFormat,
recentlyUsedRanges = [],
}) => {
const legendId = generateId();
const legendId = useGeneratedHtmlId();

if (recentlyUsedRanges.length === 0) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export class EuiRefreshInterval extends Component<
state: EuiRefreshIntervalState = fromMilliseconds(this.props.refreshInterval);

generateId = htmlIdGenerator();
legendId = this.generateId();
refreshSelectionId = this.generateId();

onValueChange: ChangeEventHandler<HTMLInputElement> = (event) => {
const sanitizedValue = parseFloat(event.target.value);
Expand Down Expand Up @@ -162,8 +164,6 @@ export class EuiRefreshInterval extends Component<
render() {
const { applyRefreshInterval, isPaused } = this.props;
const { value, units } = this.state;
const legendId = this.generateId();
const refreshSelectionId = this.generateId();

if (!applyRefreshInterval) {
return null;
Expand All @@ -175,7 +175,7 @@ export class EuiRefreshInterval extends Component<
return (
<fieldset>
<EuiTitle size="xxxs">
<legend id={legendId}>
<legend id={this.legendId}>
<EuiI18n
token="euiRefreshInterval.legend"
default="Refresh every"
Expand All @@ -191,15 +191,15 @@ export class EuiRefreshInterval extends Component<
onChange={this.onValueChange}
onKeyDown={this.handleKeyDown}
aria-label="Refresh interval value"
aria-describedby={`${refreshSelectionId} ${legendId}`}
aria-describedby={`${this.refreshSelectionId} ${this.legendId}`}
data-test-subj="superDatePickerRefreshIntervalInput"
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiSelect
compressed
aria-label="Refresh interval units"
aria-describedby={`${refreshSelectionId} ${legendId}`}
aria-describedby={`${this.refreshSelectionId} ${this.legendId}`}
value={units}
options={refreshUnitsOptions}
onChange={this.onUnitsChange}
Expand All @@ -215,7 +215,7 @@ export class EuiRefreshInterval extends Component<
onClick={this.toggleRefresh}
disabled={value === '' || value <= 0}
data-test-subj="superDatePickerToggleRefreshButton"
aria-describedby={refreshSelectionId}
aria-describedby={this.refreshSelectionId}
>
{isPaused ? (
<EuiI18n token="euiRefreshInterval.start" default="Start" />
Expand All @@ -226,7 +226,7 @@ export class EuiRefreshInterval extends Component<
</EuiFlexItem>
</EuiFlexGroup>
<EuiScreenReaderOnly>
<p id={refreshSelectionId}>
<p id={this.refreshSelectionId}>
<EuiI18n
token="euiRefreshInterval.fullDescription"
default="Refresh interval currently set to {optionValue} {optionText}."
Expand Down

0 comments on commit 841ed6f

Please sign in to comment.