Skip to content

Commit

Permalink
feat(component): add filterable prop to Select (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgemoya authored Oct 29, 2019
1 parent 00140ab commit f05d343
Showing 10 changed files with 88 additions and 19 deletions.
4 changes: 4 additions & 0 deletions packages/big-design/src/components/List/Item/styled.tsx
Original file line number Diff line number Diff line change
@@ -43,6 +43,10 @@ export const StyledListItem = styled.li<ListItemProps>`
a {
color: ${({ theme }) => theme.colors.secondary70};
}
label {
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
}
`;

StyledListItem.defaultProps = { theme: defaultTheme };
Original file line number Diff line number Diff line change
@@ -138,6 +138,10 @@ exports[`render pagination component 1`] = `
color: #313440;
}
.c8 label {
cursor: pointer;
}
.c4 {
-webkit-align-items: center;
-webkit-box-align: center;
@@ -630,6 +634,10 @@ exports[`render pagination component with invalid page info 1`] = `
color: #313440;
}
.c8 label {
cursor: pointer;
}
.c4 {
-webkit-align-items: center;
-webkit-box-align: center;
@@ -1122,6 +1130,10 @@ exports[`render pagination component with invalid range info 1`] = `
color: #313440;
}
.c8 label {
cursor: pointer;
}
.c4 {
-webkit-align-items: center;
-webkit-box-align: center;
@@ -1615,6 +1627,10 @@ exports[`render pagination component with no items 1`] = `
color: #313440;
}
.c8 label {
cursor: pointer;
}
.c4 {
-webkit-align-items: center;
-webkit-box-align: center;
29 changes: 21 additions & 8 deletions packages/big-design/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import { ListCheckboxItem } from '../List/Item/CheckboxItem';
import { ListItem } from '../List/Item/Item';
import { List } from '../List/List';

import { StyledDropdownIcon, StyledStatusMessage } from './styled';
import { StyledDropdownIcon, StyledInputContainer, StyledStatusMessage } from './styled';
import { Action, Option, SelectProps } from './types';

interface SelectState {
@@ -63,7 +63,18 @@ export class Select<T extends any> extends React.PureComponent<SelectProps<T>, S
}

render() {
const { children, label, maxHeight, multi, onChange, placeholder, placement, value, ...rest } = this.props;
const {
children,
filterable,
label,
maxHeight,
multi,
onChange,
placeholder,
placement,
value,
...rest
} = this.props;

const { isOpen } = this.state;

@@ -120,7 +131,7 @@ export class Select<T extends any> extends React.PureComponent<SelectProps<T>, S
}

private renderInput() {
const { placeholder, error, required, disabled, onChange, options, value } = this.props;
const { placeholder, error, filterable = true, required, disabled, onChange, options, value } = this.props;
const { highlightedItem, inputText, isOpen } = this.state;
const ariaActiveDescendant = highlightedItem ? { 'aria-activedescendant': highlightedItem.id } : {};
const ariaControls = isOpen ? { 'aria-controls': this.getSelectId() } : {};
@@ -143,7 +154,7 @@ export class Select<T extends any> extends React.PureComponent<SelectProps<T>, S
return (
<Reference>
{({ ref }) => (
<span ref={ref}>
<StyledInputContainer ref={ref}>
<Input
aria-autocomplete="list"
autoComplete="off"
@@ -154,17 +165,19 @@ export class Select<T extends any> extends React.PureComponent<SelectProps<T>, S
id={this.getInputId()}
onChange={this.handleOnInputChange}
onChipDelete={chips && onChipDelete}
onFocus={this.handleOnInputFocus}
onClick={this.handleOnInputSelected}
onFocus={this.handleOnInputSelected}
onKeyDown={this.handleOnInputKeyDown}
placeholder={placeholder}
readOnly={!filterable}
ref={this.inputRef}
required={required}
type={'text'}
value={inputText}
{...ariaActiveDescendant}
{...ariaControls}
></Input>
</span>
/>
</StyledInputContainer>
)}
</Reference>
);
@@ -496,7 +509,7 @@ export class Select<T extends any> extends React.PureComponent<SelectProps<T>, S
return this.updateHighlightedItem(event.currentTarget);
};

private handleOnInputFocus = () => {
private handleOnInputSelected = () => {
if (!this.state.isOpen) {
this.toggleList();
}
Original file line number Diff line number Diff line change
@@ -178,6 +178,10 @@ exports[`select action supports icons 1`] = `
color: #313440;
}
.c1 label {
cursor: pointer;
}
<div
class="c0"
>
21 changes: 21 additions & 0 deletions packages/big-design/src/components/Select/spec.tsx
Original file line number Diff line number Diff line change
@@ -538,3 +538,24 @@ test('does not forward styles', () => {
expect(container.getElementsByClassName('test').length).toBe(0);
expect(getByRole('listbox')).not.toHaveStyle('background: red');
});

test('should render a non filterable select', () => {
const { getAllByLabelText } = render(
<Select
filterable={false}
label="Countries"
onChange={onChange}
options={[
{ value: 'us', content: 'United States' },
{ value: 'mx', content: 'Mexico' },
{ value: 'ca', content: 'Canada' },
{ value: 'en', content: 'England' },
{ value: 'fr', content: 'France', disabled: true },
]}
placeholder="Choose country"
/>,
);

const input = getAllByLabelText('Countries')[0];
expect(input.getAttribute('readonly')).toBe('');
});
17 changes: 6 additions & 11 deletions packages/big-design/src/components/Select/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { ArrowDropDownIcon } from '@bigcommerce/big-design-icons';
import { theme as defaultTheme } from '@bigcommerce/big-design-theme';
import { hideVisually } from 'polished';
import styled, { DefaultTheme, StyledComponent } from 'styled-components';

import { StyledInput } from '../Input/styled';
import styled from 'styled-components';

export const StyledStatusMessage = styled.div`
${hideVisually()}
@@ -15,10 +12,8 @@ export const StyledDropdownIcon = styled(ArrowDropDownIcon)`
}
`;

export const Test = styled(StyledInput).attrs({
as: 'div',
})`
display: flex;
` as StyledComponent<'div', DefaultTheme>;

Test.defaultProps = { theme: defaultTheme };
export const StyledInputContainer = styled.span`
input[readonly] {
cursor: pointer;
}
`;
1 change: 1 addition & 0 deletions packages/big-design/src/components/Select/types.ts
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ export interface SelectProps<T> extends Omit<React.HTMLAttributes<HTMLUListEleme
action?: Action;
disabled?: boolean;
error?: string;
filterable?: boolean;
label?: string;
maxHeight?: number;
multi?: boolean;
Original file line number Diff line number Diff line change
@@ -167,6 +167,10 @@ exports[`renders a pagination component 1`] = `
color: #313440;
}
.c11 label {
cursor: pointer;
}
.c7 {
-webkit-align-items: center;
-webkit-box-align: center;
10 changes: 10 additions & 0 deletions packages/docs/PropTables/SelectPropTable.tsx
Original file line number Diff line number Diff line change
@@ -14,6 +14,16 @@ const selectProps: Prop[] = [
types: 'string',
description: 'Displays a form error around the field.',
},
{
name: 'filterable',
types: 'boolean',
defaultValue: 'true',
description: (
<>
Allows you to filter the <Code>Options</Code> in the <Code>Select</Code>.
</>
),
},
{
name: 'label',
types: 'string',
1 change: 1 addition & 0 deletions packages/docs/pages/Select/SelectPage.tsx
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ export default () => (
icon: <DeleteIcon />,
onClick: () => null,
}}
filterable={true}
label="Countries"
maxHeight={300}
onChange={handleChange}

0 comments on commit f05d343

Please sign in to comment.