Skip to content

Commit

Permalink
feature(Select): flag to put create option at top of typeahead (patte…
Browse files Browse the repository at this point in the history
  • Loading branch information
gitdallas authored and Dominik-Petrik committed Oct 13, 2022
1 parent fe3eeca commit 48efe27
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
13 changes: 12 additions & 1 deletion packages/react-core/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export interface SelectProps
isDisabled?: boolean;
/** Flag to indicate if the typeahead select allows new items */
isCreatable?: boolean;
/** Flag to indicate if create option should be at top of typeahead */
isCreateOptionOnTop?: boolean;
/** Flag indicating if placeholder styles should be applied */
hasPlaceholderStyle?: boolean;
/** @beta Flag indicating if the creatable option should set its value as a SelectOptionObject */
Expand Down Expand Up @@ -226,6 +228,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
isDisabled: false,
hasPlaceholderStyle: false,
isCreatable: false,
isCreateOptionOnTop: false,
validated: 'default',
'aria-label': '',
'aria-labelledby': '',
Expand Down Expand Up @@ -433,6 +436,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
const {
onFilter,
isCreatable,
isCreateOptionOnTop,
onCreateOption,
createText,
noResultsFoundText,
Expand Down Expand Up @@ -542,7 +546,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
} as SelectOptionObject)
: newValue;

typeaheadFilteredChildren.push(
const createSelectOption = (
<SelectOption
key={`create ${newValue}`}
value={newOptionValue}
Expand All @@ -551,6 +555,12 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
{createText} "{newValue}"
</SelectOption>
);

if (isCreateOptionOnTop) {
typeaheadFilteredChildren.unshift(createSelectOption);
} else {
typeaheadFilteredChildren.push(createSelectOption);
}
}
}

Expand Down Expand Up @@ -1020,6 +1030,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
footer,
loadingVariant,
isCreateSelectOptionObject,
isCreateOptionOnTop,
shouldResetOnSelect,
isFlipEnabled,
removeFindDomNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,3 +560,35 @@ test('applies focus styling to the create option when reached via keyboard navig

expect(createOption.parentElement).toHaveClass('pf-m-focus');
});

test('appends create option to list of options', async () => {
const user = userEvent.setup();

render(
<Select variant={SelectVariant.typeahead} onToggle={() => {}} isOpen isCreatable>
{selectOptions}
</Select>
);

const input = screen.getByRole('textbox');
await user.type(input, `m`);

const createOption = screen.getAllByRole('option')[3];
expect(createOption).toHaveTextContent('Create "m"');
});

test('prepends create option to list of options if isCreateOptionOnTop flag is set', async () => {
const user = userEvent.setup();

render(
<Select variant={SelectVariant.typeahead} onToggle={() => {}} isOpen isCreateOptionOnTop isCreatable>
{selectOptions}
</Select>
);

const input = screen.getByRole('textbox');
await user.type(input, `m`);

const createOption = screen.getAllByRole('option')[0];
expect(createOption).toHaveTextContent('Create "m"');
});
17 changes: 17 additions & 0 deletions packages/react-core/src/components/Select/examples/Select.md
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,7 @@ class TypeaheadSelectInput extends React.Component {
selected: null,
isDisabled: false,
isCreatable: false,
isCreateOptionOnTop: false,
isInputValuePersisted: false,
isInputFilterPersisted: false,
hasOnCreateOption: false,
Expand Down Expand Up @@ -1258,6 +1259,12 @@ class TypeaheadSelectInput extends React.Component {
});
};

this.toggleCreateOptionOnTop = checked => {
this.setState({
isCreateOptionOnTop: checked
});
};

this.toggleCreateNew = checked => {
this.setState({
hasOnCreateOption: checked
Expand Down Expand Up @@ -1289,6 +1296,7 @@ class TypeaheadSelectInput extends React.Component {
selected,
isDisabled,
isCreatable,
isCreateOptionOnTop,
hasOnCreateOption,
isInputValuePersisted,
isInputFilterPersisted,
Expand All @@ -1315,6 +1323,7 @@ class TypeaheadSelectInput extends React.Component {
placeholderText="Select a state"
isDisabled={isDisabled}
isCreatable={isCreatable}
isCreateOptionOnTop={isCreateOptionOnTop}
onCreateOption={(hasOnCreateOption && this.onCreateOption) || undefined}
shouldResetOnSelect={resetOnSelect}
>
Expand Down Expand Up @@ -1343,6 +1352,14 @@ class TypeaheadSelectInput extends React.Component {
id="toggle-creatable-typeahead"
name="toggle-creatable-typeahead"
/>
<Checkbox
label="isCreateOptionOnTop"
isChecked={this.state.isCreateOptionOnTop}
onChange={this.toggleCreateOptionOnTop}
aria-label="toggle createOptionOnTop checkbox"
id="toggle-create-option-on-top-typeahead"
name="toggle-create-option-on-top-typeahead"
/>
<Checkbox
label="onCreateOption"
isChecked={this.state.hasOnCreateOption}
Expand Down

0 comments on commit 48efe27

Please sign in to comment.