Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

Commit

Permalink
Add translations logic, update to functional component
Browse files Browse the repository at this point in the history
  • Loading branch information
ns065186 committed Oct 24, 2023
1 parent c164eb3 commit c5cae30
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 85 deletions.
131 changes: 61 additions & 70 deletions packages/terra-slider/src/Slider.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React from 'react';
import React, {
useContext, useState, useRef,
} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames/bind';
import ThemeContext from 'terra-theme-context';
import VisuallyHiddenText from 'terra-visually-hidden-text';
import { injectIntl } from 'react-intl';
import { v4 as uuidv4 } from 'uuid';
import styles from './Slider.module.scss';

Expand Down Expand Up @@ -48,84 +51,72 @@ const propTypes = {
* Function to trigger when user changes the input value. Sends parameter {Event} event.
*/
onChange: PropTypes.func,

/**
* @private
* The intl object containing translations. This is retrieved from the context automatically by injectIntl.
*/
intl: PropTypes.shape({ formatMessage: PropTypes.func, locale: PropTypes.string }),
};

const defaultProps = {
isDisabled: false,
onChange: undefined,
};

class Slider extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.value,
};
this.handleOnChange = this.handleOnChange.bind(this);
this.sliderRef = React.createRef();
}

componentDidUpdate(prevProps) {
if (this.props.value === prevProps.value) {
return;
const Slider = props => {
const {
isDisabled,
intl,
minimumValue,
maximumValue,
label,
minimumLabel,
maximumLabel,
} = props;

const theme = useContext(ThemeContext);
const sliderClassNames = cx([
'slider',
theme.className,
]);
const sliderRef = useRef();
const minLabel = minimumLabel || minimumValue;
const maxLabel = maximumLabel || maximumValue;
const visuallyHiddenTextValue = (minimumLabel && maximumLabel)
? intl.formatMessage({ id: 'Terra.slider.ariaDescribedByTextWithLabels' }, {
minimumLabel, maximumLabel, minimumValue, maximumValue,
})
: intl.formatMessage({ id: 'Terra.slider.ariaDescribedByTextWithoutLabels' }, { minimumValue, maximumValue });
const descriptionId = uuidv4();
const [value, setValue] = useState(props.value);

const handleOnChange = (event) => {
setValue(event.currentTarget.value);
if (props.onChange) {
props.onChange(event);
}
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
value: this.props.value,
});
}

handleOnChange(event) {
this.setState({ value: event.currentTarget.value });
if (this.props.onChange) {
this.props.onChange(event);
}
}

render() {
const {
isDisabled,
minimumValue,
maximumValue,
label,
minimumLabel,
maximumLabel,
} = this.props;

const theme = this.context;
const sliderClassNames = cx([
'slider',
theme.className,
]);

const minLabel = minimumLabel || minimumValue;
const maxLabel = maximumLabel || maximumValue;
const visuallyHiddenTextValue = (minimumLabel || maximumLabel)
? `Adjust slider to select a value between ${minimumLabel} (${minimumValue}) and ${maximumLabel} (${maximumValue})`
: `Adjust slider to select a value between ${minimumValue} and ${maximumValue}`;
const descriptionId = uuidv4();

return (
/* eslint-disable-next-line react/forbid-dom-props */
<div style={{ '--terra-slider-progress-status': `${this.state.value}%` }} className={sliderClassNames}>
<span className={cx('label')} aria-hidden="true">
{label}
</span>
<span className={cx('slider-label', 'slider-min-label')} aria-hidden="true">
{minLabel}
</span>
<input className={cx('input-range')} type="range" ref={this.sliderRef} aria-label={label} aria-describedby={descriptionId} value={this.state.value} disabled={isDisabled} min={minimumValue} max={maximumValue} onChange={this.handleOnChange} />
<span className={cx('slider-label', 'slider-max-label')} aria-hidden="true">
{maxLabel}
</span>
<VisuallyHiddenText id={descriptionId} text={visuallyHiddenTextValue} />
</div>
);
}
}
};

return (
/* eslint-disable-next-line react/forbid-dom-props */
<div style={{ '--terra-slider-progress-status': `${value}%` }} className={sliderClassNames}>
<span className={cx('label')} aria-hidden="true">
{label}
</span>
<span className={cx('slider-label', 'slider-min-label')} aria-hidden="true">
{minLabel}
</span>
<input className={cx('input-range')} type="range" ref={sliderRef} aria-label={label} aria-describedby={descriptionId} value={value} disabled={isDisabled} min={minimumValue} max={maximumValue} onChange={handleOnChange} />
<span className={cx('slider-label', 'slider-max-label')} aria-hidden="true">
{maxLabel}
</span>
<VisuallyHiddenText id={descriptionId} text={visuallyHiddenTextValue} />
</div>
);
};

Slider.propTypes = propTypes;
Slider.defaultProps = defaultProps;
Slider.contextType = ThemeContext;

export default Slider;
export default injectIntl(Slider);
21 changes: 11 additions & 10 deletions packages/terra-slider/tests/jest/Slider.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';
import { v4 as uuidv4 } from 'uuid';
/* eslint-disable-next-line import/no-extraneous-dependencies */
import { shallowWithIntl } from 'terra-enzyme-intl';
import Slider from '../../src/Slider';

let mockSpyUuid;
Expand All @@ -13,9 +15,9 @@ afterAll(() => {

describe('Slider', () => {
it('should render a default slider with proper required props', () => {
const wrapper = shallow(
const wrapper = shallowWithIntl(
<Slider minimumValue={0} maximumValue={100} label="testLabel" value={30} />,
);
).dive();
expect(wrapper).toMatchSnapshot();
expect(wrapper.find('.label').text()).toEqual('testLabel');
expect(wrapper.find('input').prop('min')).toEqual(0);
Expand All @@ -24,29 +26,28 @@ describe('Slider', () => {
});

it('should render a disabled slider', () => {
const wrapper = shallow(
const wrapper = shallowWithIntl(
<Slider isDisabled minimumValue={0} maximumValue={100} label="testLabel" value={50} />,
);
).dive();
expect(wrapper.find('input').prop('disabled')).toEqual(true);
expect(wrapper).toMatchSnapshot();
});

it('should render a slider with custom min and max labels', () => {
const wrapper = shallow(
const wrapper = shallowWithIntl(
<Slider minimumValue={0} maximumValue={100} label="testLabel" minimumLabel="testMinimumLabel" maximumLabel="testMaximumLabel" value={50} />,
);
).dive();
expect(wrapper.find('.slider-label').at(0).text()).toEqual('testMinimumLabel');
expect(wrapper.find('.slider-max-label').text()).toEqual('testMaximumLabel');
expect(wrapper).toMatchSnapshot();
});

it('should update slider value correctly ', () => {
const wrapper = shallow(
const wrapper = shallowWithIntl(
<Slider isDisabled minimumValue={0} maximumValue={100} label="testLabel" value={50} />,
);
expect(wrapper.find('input').prop('value')).toEqual(50);
expect(wrapper.dive().find('input').prop('value')).toEqual(50);
wrapper.setProps({ value: 30 });
wrapper.update();
expect(wrapper.find('input').prop('value')).toEqual(30);
expect(wrapper.dive().find('input').prop('value')).toEqual(30);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ exports[`Slider should render a default slider with proper required props 1`] =
</span>
<VisuallyHiddenText
id="00000000-0000-0000-0000-000000000000"
text="Adjust slider to select a value between 0 and 100"
text="Terra.slider.ariaDescribedByTextWithoutLabels"
/>
</div>
`;
Expand Down Expand Up @@ -85,7 +85,7 @@ exports[`Slider should render a disabled slider 1`] = `
</span>
<VisuallyHiddenText
id="00000000-0000-0000-0000-000000000000"
text="Adjust slider to select a value between 0 and 100"
text="Terra.slider.ariaDescribedByTextWithoutLabels"
/>
</div>
`;
Expand Down Expand Up @@ -130,7 +130,7 @@ exports[`Slider should render a slider with custom min and max labels 1`] = `
</span>
<VisuallyHiddenText
id="00000000-0000-0000-0000-000000000000"
text="Adjust slider to select a value between testMinimumLabel (0) and testMaximumLabel (100)"
text="Terra.slider.ariaDescribedByTextWithLabels"
/>
</div>
`;
3 changes: 2 additions & 1 deletion packages/terra-slider/translations/en-US.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"Terra.slider.Slider": "Slider"
"Terra.slider.ariaDescribedByTextWithLabels": "Adjust slider to select a value between {minimumLabel} ({minimumValue}) and {maximumLabel} ({maximumValue})",
"Terra.slider.ariaDescribedByTextWithoutLabels": "Adjust slider to select a value between {minimumValue} and {maximumValue}"
}
3 changes: 2 additions & 1 deletion packages/terra-slider/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"Terra.slider.Slider": "Slider"
"Terra.slider.ariaDescribedByTextWithLabels": "Adjust slider to select a value between {minimumLabel} ({minimumValue}) and {maximumLabel} ({maximumValue})",
"Terra.slider.ariaDescribedByTextWithoutLabels": "Adjust slider to select a value between {minimumValue} and {maximumValue}"
}

0 comments on commit c5cae30

Please sign in to comment.