Skip to content

Commit

Permalink
feat(project): add dropdown component
Browse files Browse the repository at this point in the history
  • Loading branch information
demmyhonore committed Apr 30, 2021
1 parent ca52c6b commit 8079987
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/components/Dropdown/Dropdown.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
$select-border: #777;
$select-focus: blue;
$select-arrow: $select-border;

select {
appearance: none;
background-color: transparent;
border: none;
padding: 0 1em 0 0;
margin: 0;
width: 100%;
font-family: inherit;
font-size: 1rem;
font-weight: 700;
cursor: inherit;
line-height: inherit;
z-index: 1;
outline: none;

// Remove IE arrow
&::-ms-expand {
display: none;
}
}

.dropdown {
display: grid;
grid-template-areas: "select";
align-items: center;
position: relative;
min-width: 10ch;
max-width: 20ch;
border: 1px solid $select-border;
border-radius: 0.25em;
padding: 0.5em 0.8em;
font-size: 1.25rem;
cursor: pointer;
line-height: 1.1;
background-color: #fff;
background-image: linear-gradient(to top, #f9f9f9, #fff 33%);

select,
&::after {
grid-area: select;
}

// Custom arrow
&::after {
content: "";
justify-self: end;
width: 0.6em;
height: 0.4em;
background-color: $select-arrow;
clip-path: polygon(100% 0%, 0 0%, 50% 100%);
}

&:focus + .focus {
position: absolute;
top: -1px;
left: -1px;
right: -1px;
bottom: -1px;
border: 2px solid $select-focus;
border-radius: inherit;
}

& .disabled {
cursor: not-allowed;
background-color: #eee;
background-image: linear-gradient(to top, #ddd, #eee 33%);
}
}

option {
white-space: normal;

// Set focus on chrome
outline-color: $select-focus;
}
21 changes: 21 additions & 0 deletions src/components/Dropdown/Dropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react';
import { render } from '@testing-library/react';

import Dropdown from './Dropdown';

const options = ["x", "y", "z"]

describe('<Dropdown>', () => {
it('renders dropdown', () => {
const { getByText } = render((
<Dropdown
name="categories"
value="aa"
defaultLabel="bb"
options={options}
setValue={(event) => event}
/>));
const dropdown = getByText(/bb/i);
expect(document.body.contains(dropdown));
});
});
34 changes: 34 additions & 0 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';

import styles from './Dropdown.module.scss';

type DropdownProps = {
name: string;
value: string;
defaultLabel: string;
options: string[];
setValue: ((value: string) => void);
};

function Dropdown({
name,
value,
defaultLabel,
options,
setValue
}: DropdownProps) {

const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => setValue(event.target.value)

return (
<div className={styles.dropdown}>
<select name={name} value={value} onChange={handleChange}>
<option value="">{defaultLabel}</option>
{options.map(option => <option key={option} value={option}>{option}</option>)}
</select>
<span className="focus"></span>
</div>
);
}

export default Dropdown;

0 comments on commit 8079987

Please sign in to comment.