Skip to content

Commit

Permalink
feat(playlist): made filters responsive
Browse files Browse the repository at this point in the history
  • Loading branch information
RCVZ committed May 4, 2021
1 parent 4f344ad commit f833add
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 58 deletions.
90 changes: 52 additions & 38 deletions src/components/Dropdown/Dropdown.module.scss
Original file line number Diff line number Diff line change
@@ -1,82 +1,96 @@
@use '../../styles/variables';
@use '../../styles/theme';
@use '../../styles/mixins/responsive';

$select-border: variables.$gray-lighter;
$select-arrow: variables.$black;
$select-focus: theme.$primary-color;

.filterRow {
@include responsive.mobile-only() {
display: none;
}
display: flex;
align-items: center;
margin-left: 16px;
padding-top: 8px;
}

.dropdown {
position: relative;
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;
margin-left: 24px;
padding: 0.2em 0.4em;
font-size: 1.25rem;
cursor: pointer;
line-height: 1.1;
background-color: #fff;
background-image: linear-gradient(to top, #f9f9f9, #fff 33%);
border: 1px solid $select-border;
border-radius: 0.25em;
cursor: pointer;
grid-template-areas: 'select';

.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;
// Custom arrow
&::after {
width: 0.6em;
height: 0.4em;
background-color: $select-arrow;
clip-path: polygon(100% 0%, 0 0%, 50% 100%);
content: '';
justify-self: end;
}

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

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

.select,
.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%);
& .disabled {
background-color: #eee;
background-image: linear-gradient(to top, #ddd, #eee 33%);
cursor: not-allowed;
}

&:focus + .focus {
position: absolute;
top: -1px;
left: -1px;
right: -1px;
bottom: -1px;
left: -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 {
@include responsive.mobile-only() {
display: none;
}
white-space: normal;

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

import '../../hooks/matchMedia.mock';
import Dropdown from './Dropdown';

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

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

import FilterModal from '../FilterModal/FilterModal';
import Button from '../Button/Button';
import useBreakpoint, { Breakpoint } from '../../hooks/useBreakpoint';

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

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

function Dropdown({
const Dropdown: FC<Props> = ({
name,
value,
defaultLabel,
options,
setValue
}: DropdownProps) {
setValue,
}) => {
const [isFilterModalOpen, openFilterModal] = useState(false);
const breakpoint: Breakpoint = useBreakpoint();

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

const handleOnClick = () => {
if (breakpoint < 2) {
openFilterModal(true);
}
};

const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => setValue(event.target.value)
const filterButtons = () => {
const extraOptions = options.map((option) => (
<Button
label={option}
onClick={() => setValue(option)}
key={option}
active={value === option}
/>
));

return [
<Button
label={defaultLabel}
onClick={() => setValue('')}
active={value === ''}
key={defaultLabel}
/>,
...extraOptions,
];
};

const showFilterRow = breakpoint >= 2 && options.length < 6;

return (
<div className={styles.dropdown}>
<select className={styles.select} name={name} value={value} onChange={handleChange}>
<option value="">{defaultLabel}</option>
{options.map(option => <option className={styles.option} key={option} value={option}>{option}</option>)}
</select>
<span className="focus"></span>
</div>
<Fragment>
<FilterModal
name={name}
isOpen={isFilterModalOpen}
onClose={() => openFilterModal(false)}
>
{filterButtons()}
</FilterModal>
{showFilterRow ? (
<div className={styles.filterRow}>{filterButtons()}</div>
) : (
<div className={styles.dropdown}>
<select
className={styles.select}
name={name}
value={value}
onClick={handleOnClick}
onChange={handleChange}
>
<option className={styles.option} value="">
{defaultLabel}
</option>
{options.map((option) => (
<option className={styles.option} key={option} value={option}>
{option}
</option>
))}
</select>
<span className="focus" />
</div>
)}
</Fragment>
);
}
};

export default Dropdown;
103 changes: 103 additions & 0 deletions src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Dropdown> renders dropdown 1`] = `
<div>
<div
class="filterModal"
>
<div
aria-label="close menu"
class="header"
role="button"
>
<svg
aria-hidden="true"
class="icon"
focusable="false"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
/>
<path
d="M0 0h24v24H0z"
fill="none"
/>
</g>
</svg>
<h4>
categories
</h4>
</div>
<hr
class="divider"
/>
<div
class="group"
>
<button
class="button"
>
<span>
bb
</span>
</button>
<button
class="button"
>
<span>
x
</span>
</button>
<button
class="button"
>
<span>
y
</span>
</button>
<button
class="button"
>
<span>
z
</span>
</button>
</div>
</div>
<div
class="filterRow"
>
<button
class="button"
>
<span>
bb
</span>
</button>
<button
class="button"
>
<span>
x
</span>
</button>
<button
class="button"
>
<span>
y
</span>
</button>
<button
class="button"
>
<span>
z
</span>
</button>
</div>
</div>
`;

0 comments on commit f833add

Please sign in to comment.