-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(playlist): made filters responsive
- Loading branch information
Showing
4 changed files
with
237 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
103
src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
`; |