Skip to content

Commit

Permalink
feat: exposing value prop on select
Browse files Browse the repository at this point in the history
  • Loading branch information
Ibabalola committed Jul 7, 2021
1 parent cac2d91 commit fbbf58d
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 22 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
## 0.2.1 (07/07/2021)
## 0.2.2 (07/07/2021)

<a name="0.2.2"></a>

- [select with value](https://github.com/Capgemini/dcx-react-library/issues/213)

## 0.2.1 (06/07/2021)

<a name="0.2.1"></a>

- [formInput with nullOption](https://github.com/Capgemini/dcx-react-library/issues/210)
- [select with nullOption](https://github.com/Capgemini/dcx-react-library/issues/210)

## 0.2.0 (02/07/2021)

Expand Down
28 changes: 17 additions & 11 deletions src/formSelect/FormSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export type FormSelectProps = {
* nullOption will be selected by default
*/
nullOption?: string;
/**
* select value which is programatically added by user
*/
value?: number | string;
};

export const FormSelect = ({
Expand All @@ -66,6 +70,7 @@ export const FormSelect = ({
optionGroups,
options = [],
onChange,
value,
id,
ariaLabel,
label,
Expand All @@ -87,16 +92,17 @@ export const FormSelect = ({
option => option.selected
);

const initialValue: string =
nullOption !== undefined
? nullOption
: preselectedValue !== undefined
? preselectedValue.value
: options.length
? options[0].value
: '';
const initialValue: string | number = value
? value
: nullOption !== undefined
? nullOption
: preselectedValue !== undefined
? preselectedValue.value
: options.length
? options[0].value
: '';

const [value, setValue] = useState<string>(initialValue);
const [selectValue, setSelectValue] = useState<string | number>(initialValue);

const getOptions = (options: OptionProps[]): JSX.Element[] =>
options.map((item: OptionProps, index: number) => (
Expand All @@ -109,7 +115,7 @@ export const FormSelect = ({
));

const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
setValue(event.target.value);
setSelectValue(event.currentTarget.value);
if (onChange) onChange(event);
};

Expand All @@ -123,7 +129,7 @@ export const FormSelect = ({
{hint && <Hint {...hint} />}
{error && <ErrorMessage {...error} />}
<select
value={value}
value={selectValue}
name={name || 'formSelect'}
id={id || 'formSelect'}
className={className}
Expand Down
70 changes: 69 additions & 1 deletion src/formSelect/__test__/FormSelect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const DummySelect = ({
options = [{ label: 'option1', value: 'value1' }],
optionGroups,
nullOption = undefined,
value,
}: FormSelectProps) => (
<FormSelect
className={className}
Expand All @@ -30,6 +31,7 @@ const DummySelect = ({
error={error}
optionGroups={optionGroups}
nullOption={nullOption}
value={value}
/>
);

Expand Down Expand Up @@ -318,7 +320,7 @@ describe('FormSelect', () => {
options: [
{ label: 'option1', value: 'value1' },
{ label: 'option2', value: 'value2' },
{ label: 'option3', value: 'value3', selected: true },
{ label: 'option3', value: 'value3' },
],
displayCount: true,
},
Expand Down Expand Up @@ -347,4 +349,70 @@ describe('FormSelect', () => {
const formSelect = screen.getByRole('combobox');
expect(formSelect).toHaveDisplayValue('Select...');
});

it('should allow a value prop in order for a programmatic change', () => {
const options: OptionProps[] = [
{ label: 'option1', value: 'value1' },
{ label: 'option2', value: 'value2' },
{ label: 'option3', value: 'value3' },
{ label: 'option4', value: 'value4' },
];

render(
<DummySelect
id="myId"
name="the name"
options={options}
nullOption="Select..."
value="value4"
/>
);

const formSelect = screen.getByRole('combobox');
expect(formSelect).toHaveDisplayValue('option4');
});

it('should allow a value prop default value', () => {
const options: OptionProps[] = [
{ label: 'option1', value: 'value1' },
{ label: 'option2', value: 'value2' },
{ label: 'option3', value: 'value3' },
{ label: 'option4', value: 'value4' },
];

render(
<DummySelect
id="myId"
name="the name"
options={options}
nullOption="Select..."
value=""
/>
);

const formSelect = screen.getByRole('combobox');
expect(formSelect).toHaveDisplayValue('Select...');
});

it('should not allow a value prop for a non-existent option', () => {
const options: OptionProps[] = [
{ label: 'option1', value: 'value1' },
{ label: 'option2', value: 'value2' },
{ label: 'option3', value: 'value3' },
{ label: 'option4', value: 'value4' },
];

render(
<DummySelect
id="myId"
name="the name"
options={options}
nullOption="Select..."
value="value5"
/>
);

const formSelect = screen.getByRole('combobox');
expect(formSelect).toHaveDisplayValue('Select...');
});
});
1 change: 1 addition & 0 deletions stories/FormSelect/Documentation.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ An example with all the available properties is:
onChange={handleChange}
name="select-name"
id="select-id"
value="select-value"
optionProps={{
className: "select options classes"
}}
Expand Down
40 changes: 32 additions & 8 deletions stories/FormSelect/Styled.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,41 @@ In this section we're using the formSelect component providing the GovUk style p
{ label: 'Most views', value: 'views' },
{ label: 'Most comments', value: 'comments' },
]}
id="sort-2"
id="sort-3"
label="Sort by"
labelProps={{
className: 'govuk-label',
}}
name="sort-2"
hint={{
text:
'This is and example of hintText/description and a predefined Option of what we need from you',
className: 'govuk-hint',
name="sort-3"
/>
</div>
);
}}
</Story>
</Canvas>

# Select with value

<Canvas>
<Story name="select with value">
{() => {
return (
<div className="govuk-form-group">
<FormSelect
value='comments'
className="govuk-select"
options={[
{ label: 'Recently published', value: 'published' },
{ label: 'Recently updated', value: 'updated' },
{ label: 'Most views', value: 'views' },
{ label: 'Most comments', value: 'comments' },
]}
id="sort-4"
label="Sort by"
labelProps={{
className: 'govuk-label',
}}
name="sort-4"
/>
</div>
);
Expand All @@ -116,12 +140,12 @@ In this section we're using the formSelect component providing the GovUk style p
{ label: 'Most views', value: 'views' },
{ label: 'Most comments', value: 'comments' },
]}
id="sort-2"
id="sort-5"
label="Sort by"
labelProps={{
className: 'govuk-label',
}}
name="sort-2"
name="sort-5"
error={{
text: 'Select an option',
className: 'govuk-error-message',
Expand Down
29 changes: 29 additions & 0 deletions stories/FormSelect/UnStyled.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,35 @@ import { FormSelect } from '../../src/formSelect/FormSelect';
</Story>
</Canvas>

### Examples of value Select

<Canvas>
<Story name="value">
{() => {
return (
<FormSelect
value="value4"
label="value"
labelProps={{
style: {
display: 'block',
marginBottom: '5px',
fontSize: '20px',
fontWeight: 'bold',
},
}}
options={[
{ label: 'option1', value: 'value1' },
{ label: 'option2', value: 'value2' },
{ label: 'option3', value: 'value3' },
{ label: 'option4', value: 'value4' },
]}
/>
);
}}
</Story>
</Canvas>

### Properties

<Props of={FormSelect} />
1 change: 1 addition & 0 deletions stories/liveEdit/FormSelectLive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function FormSelectDemo() {
optionGroups={[]}
className=""
id="select"
value=""
ariaLabel=""
labelProps={{}}
hint={{
Expand Down

0 comments on commit fbbf58d

Please sign in to comment.