Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/DualListSelector/dual-list-selector';
import { css } from '@patternfly/react-styles';
import formStyles from '@patternfly/react-styles/css/components/FormControl/form-control';
import { DualListSelectorTree, DualListSelectorTreeItemData } from './DualListSelectorTree';
import { getUniqueId } from '../../helpers';
import { DualListSelectorListWrapper } from './DualListSelectorListWrapper';
import { DualListSelectorContext, DualListSelectorPaneContext } from './DualListSelectorContext';
import { DualListSelectorList } from './DualListSelectorList';
import { SearchInput } from '../SearchInput';

/** Acts as the container for a list of options that are either available or chosen,
* depending on the pane type (available or chosen). A search input and other actions,
Expand Down Expand Up @@ -57,6 +57,8 @@ export interface DualListSelectorPaneProps {
onSearch?: (event: React.ChangeEvent<HTMLInputElement>) => void;
/** @hide A callback for when the search input value for changes. To be used when isSearchable is true. */
onSearchInputChanged?: (value: string, event: React.FormEvent<HTMLInputElement>) => void;
/** @hide Callback for search input clear button */
onSearchInputClear?: (event: React.SyntheticEvent<HTMLButtonElement>) => void;
/** @hide Filter function for custom filtering based on search string. To be used when isSearchable is true. */
filterOption?: (option: React.ReactNode, input: string) => boolean;
/** @hide Accessible label for the search input. To be used when isSearchable is true. */
Expand All @@ -81,6 +83,7 @@ export const DualListSelectorPane: React.FunctionComponent<DualListSelectorPaneP
searchInputAriaLabel = '',
onFilterUpdate,
onSearchInputChanged,
onSearchInputClear,
filterOption,
id = getUniqueId('dual-list-selector-pane'),
isDisabled = false,
Expand All @@ -90,8 +93,7 @@ export const DualListSelectorPane: React.FunctionComponent<DualListSelectorPaneP
const { isTree } = React.useContext(DualListSelectorContext);

// only called when search input is dynamically built
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
const onChange = (newValue: string, e: React.FormEvent<HTMLInputElement>) => {
let filtered: React.ReactNode[];
if (isTree) {
filtered = options
Expand Down Expand Up @@ -160,12 +162,14 @@ export const DualListSelectorPane: React.FunctionComponent<DualListSelectorPaneP
{searchInput ? (
searchInput
) : (
<input
className={css(formStyles.formControl, formStyles.modifiers.search)}
type="search"
<SearchInput
onChange={isDisabled ? undefined : onChange}
onClear={
onSearchInputClear ? onSearchInputClear : e => onChange('', e as React.FormEvent<HTMLInputElement>)
}
isDisabled={isDisabled}
aria-label={searchInputAriaLabel}
disabled={isDisabled}
type="search"
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1135,11 +1135,41 @@ exports[`DualListSelector with search inputs 1`] = `
<div
class="pf-c-dual-list-selector__tools-filter"
>
<input
aria-label="Available search input"
class="pf-c-form-control pf-m-search"
type="search"
/>
<div
class="pf-c-text-input-group"
>
<div
class="pf-c-text-input-group__main pf-m-icon"
>
<span
class="pf-c-text-input-group__text"
>
<span
class="pf-c-text-input-group__icon"
>
<svg
aria-hidden="true"
fill="currentColor"
height="1em"
role="img"
style="vertical-align: -0.125em;"
viewBox="0 0 512 512"
width="1em"
>
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
/>
</svg>
</span>
<input
aria-label="Available search input"
class="pf-c-text-input-group__text-input"
type="search"
value=""
/>
</span>
</div>
</div>
</div>
</div>
<div
Expand Down Expand Up @@ -1360,11 +1390,41 @@ exports[`DualListSelector with search inputs 1`] = `
<div
class="pf-c-dual-list-selector__tools-filter"
>
<input
aria-label="Chosen search input"
class="pf-c-form-control pf-m-search"
type="search"
/>
<div
class="pf-c-text-input-group"
>
<div
class="pf-c-text-input-group__main pf-m-icon"
>
<span
class="pf-c-text-input-group__text"
>
<span
class="pf-c-text-input-group__icon"
>
<svg
aria-hidden="true"
fill="currentColor"
height="1em"
role="img"
style="vertical-align: -0.125em;"
viewBox="0 0 512 512"
width="1em"
>
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
/>
</svg>
</span>
<input
aria-label="Chosen search input"
class="pf-c-text-input-group__text-input"
type="search"
value=""
/>
</span>
</div>
</div>
</div>
</div>
<div
Expand Down
15 changes: 15 additions & 0 deletions packages/react-core/src/components/SearchInput/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ export interface SearchInputProps extends Omit<React.HTMLProps<HTMLDivElement>,
hasWordsAttrLabel?: React.ReactNode;
/** A suggestion for autocompleting. */
hint?: string;
/** Type of the input */
type?:
| 'text'
| 'date'
| 'datetime-local'
| 'email'
| 'month'
| 'number'
| 'password'
| 'search'
| 'tel'
| 'time'
| 'url';
/** @hide A reference object to attach to the input box. */
innerRef?: React.RefObject<any>;
/** A flag for controlling the open state of a custom advanced search implementation. */
Expand Down Expand Up @@ -147,6 +160,7 @@ const SearchInputBase: React.FunctionComponent<SearchInputProps> = ({
isDisabled = false,
appendTo,
removeFindDomNode = false,
type = 'text',
...props
}: SearchInputProps) => {
const [isSearchMenuOpen, setIsSearchMenuOpen] = React.useState(false);
Expand Down Expand Up @@ -263,6 +277,7 @@ const SearchInputBase: React.FunctionComponent<SearchInputProps> = ({
aria-label={ariaLabel}
onKeyDown={onEnter}
onChange={onChangeHandler}
type={type}
/>
{renderUtilities && (
<TextInputGroupUtilities>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ describe('Dual List Selector BasicDemo Test', () => {
.eq(1)
.find('li')
.should('have.length', 4);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(1)
.type('Option 1');
cy.get('.pf-c-dual-list-selector__list')
Expand All @@ -179,7 +179,7 @@ describe('Dual List Selector BasicDemo Test', () => {
});

it('Verify removing all options', () => {
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(1)
.type('{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}');
cy.get('.pf-c-dual-list-selector__controls-item')
Expand Down Expand Up @@ -216,7 +216,7 @@ describe('Dual List Selector BasicDemo Test', () => {
.eq(0)
.find('li')
.should('have.length', 4);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('Option 3');
cy.get('.pf-c-dual-list-selector__list')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ describe('Dual List Selector TreeDemo Test', () => {
.eq(0)
.find('li')
.should('have.length', 4);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('Option 2');
cy.get('.pf-c-dual-list-selector__list')
.eq(0)
.find('li')
.should('have.length', 1);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}');
cy.get('.pf-c-dual-list-selector__list-item .pf-c-dual-list-selector__item-toggle')
Expand Down Expand Up @@ -75,7 +75,7 @@ describe('Dual List Selector TreeDemo Test', () => {
.eq(0)
.find('li')
.should('have.length', 3);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('Option 1');
cy.get('.pf-c-dual-list-selector__list')
Expand All @@ -89,7 +89,7 @@ describe('Dual List Selector TreeDemo Test', () => {
.eq(1)
.find('li')
.should('have.length', 3);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}');
cy.get('.pf-c-dual-list-selector__list')
Expand All @@ -103,7 +103,7 @@ describe('Dual List Selector TreeDemo Test', () => {
.eq(1)
.find('li')
.should('have.length', 3);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(1)
.type('Option 1');
cy.get('.pf-c-dual-list-selector__list')
Expand Down Expand Up @@ -132,7 +132,7 @@ describe('Dual List Selector TreeDemo Test', () => {
.eq(1)
.find('li')
.should('have.length', 0);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(1)
.type('{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}{backspace}');
cy.get('.pf-c-dual-list-selector__list')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe('Dual List Selector With Actions Demo Test', () => {
.eq(1)
.find('li')
.should('have.length', 4);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(1)
.type('Option 1');
cy.get('.pf-c-dual-list-selector__list')
Expand All @@ -161,7 +161,7 @@ describe('Dual List Selector With Actions Demo Test', () => {
});

it('Verify removing all options', () => {
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(1)
.type('{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}');
cy.get('.pf-c-dual-list-selector__controls-item')
Expand All @@ -182,7 +182,7 @@ describe('Dual List Selector With Actions Demo Test', () => {
.eq(0)
.find('li')
.should('have.length', 4);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('Option 3');
cy.get('.pf-c-dual-list-selector__list')
Expand All @@ -207,7 +207,7 @@ describe('Dual List Selector With Actions Demo Test', () => {
.eq(1)
.find('li')
.should('have.length', 1);
cy.get('.pf-c-dual-list-selector__tools-filter .pf-m-search')
cy.get('.pf-c-dual-list-selector__tools-filter input')
.eq(0)
.type('{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}');
cy.get('.pf-c-dual-list-selector__list')
Expand Down