refactor: extract dropdown for Sort dropdown

This commit is contained in:
Sammy Teillet
2023-04-24 18:05:29 +02:00
parent 795f9e7af8
commit 0f4dcc1957
3 changed files with 52 additions and 31 deletions

View File

@ -1,6 +1,5 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useRef, ReactNode } from 'react';
import { useState, useRef } from 'react';
import { useOutsideAlerter } from '../../../hooks/useOutsideAlerter'; import { useOutsideAlerter } from '../../../hooks/useOutsideAlerter';
import { modalBackground } from '../../../layout/styles/themes'; import { modalBackground } from '../../../layout/styles/themes';
import { SortType } from './SortAndFilterBar'; import { SortType } from './SortAndFilterBar';
@ -10,6 +9,9 @@ type OwnProps = {
options: Array<SortType>; options: Array<SortType>;
isActive: boolean; isActive: boolean;
onSortSelect?: (id: string) => void; onSortSelect?: (id: string) => void;
children?: ReactNode;
isUnfolded?: boolean;
setIsUnfolded?: React.Dispatch<React.SetStateAction<boolean>>;
}; };
const StyledDropdownButtonContainer = styled.div` const StyledDropdownButtonContainer = styled.div`
@ -88,15 +90,20 @@ const StyledIcon = styled.div`
margin-right: ${(props) => props.theme.spacing(1)}; margin-right: ${(props) => props.theme.spacing(1)};
`; `;
function DropdownButton({ label, options, onSortSelect, isActive }: OwnProps) { function DropdownButton({
const [isUnfolded, setIsUnfolded] = useState(false); label,
options,
isActive,
children,
isUnfolded = false,
setIsUnfolded,
}: OwnProps) {
const onButtonClick = () => { const onButtonClick = () => {
setIsUnfolded(!isUnfolded); setIsUnfolded && setIsUnfolded(!isUnfolded);
}; };
const onOutsideClick = () => { const onOutsideClick = () => {
setIsUnfolded(false); setIsUnfolded && setIsUnfolded(false);
}; };
const dropdownRef = useRef(null); const dropdownRef = useRef(null);
@ -112,27 +119,13 @@ function DropdownButton({ label, options, onSortSelect, isActive }: OwnProps) {
{label} {label}
</StyledDropdownButton> </StyledDropdownButton>
{isUnfolded && options.length > 0 && ( {isUnfolded && options.length > 0 && (
<StyledDropdown ref={dropdownRef}> <StyledDropdown ref={dropdownRef}>{children}</StyledDropdown>
{options.map((option, index) => (
<StyledDropdownItem
key={index}
onClick={() => {
setIsUnfolded(false);
if (onSortSelect) {
onSortSelect(option.id);
}
}}
>
<StyledIcon>
{option.icon && <FontAwesomeIcon icon={option.icon} />}
</StyledIcon>
{option.label}
</StyledDropdownItem>
))}
</StyledDropdown>
)} )}
</StyledDropdownButtonContainer> </StyledDropdownButtonContainer>
); );
} }
DropdownButton.StyledDropdownItem = StyledDropdownItem;
DropdownButton.StyledIcon = StyledIcon;
export default DropdownButton; export default DropdownButton;

View File

@ -1,11 +1,12 @@
import { useCallback } from 'react'; import { useCallback, useState } from 'react';
import DropdownButton from './DropdownButton'; import DropdownButton from './DropdownButton';
import { SortType } from './SortAndFilterBar'; import { SortType } from './SortAndFilterBar';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
type OwnProps = { type OwnProps = {
sorts: SortType[]; sorts: SortType[];
setSorts: any; setSorts: (sorts: SortType[]) => void;
sortsAvailable: any; sortsAvailable: SortType[];
}; };
export function SortDropdownButton({ export function SortDropdownButton({
@ -13,6 +14,8 @@ export function SortDropdownButton({
setSorts, setSorts,
sorts, sorts,
}: OwnProps) { }: OwnProps) {
const [isUnfolded, setIsUnfolded] = useState(false);
const onSortItemSelect = useCallback( const onSortItemSelect = useCallback(
(sortId: string) => { (sortId: string) => {
const newSorts = [ const newSorts = [
@ -33,6 +36,23 @@ export function SortDropdownButton({
options={sortsAvailable} options={sortsAvailable}
onSortSelect={onSortItemSelect} onSortSelect={onSortItemSelect}
isActive={sorts.length > 0} isActive={sorts.length > 0}
/> isUnfolded={isUnfolded}
setIsUnfolded={setIsUnfolded}
>
{sortsAvailable.map((option, index) => (
<DropdownButton.StyledDropdownItem
key={index}
onClick={() => {
setIsUnfolded(false);
onSortItemSelect(option.id);
}}
>
<DropdownButton.StyledIcon>
{option.icon && <FontAwesomeIcon icon={option.icon} />}
</DropdownButton.StyledIcon>
{option.label}
</DropdownButton.StyledDropdownItem>
))}
</DropdownButton>
); );
} }

View File

@ -80,14 +80,22 @@ function TableHeader({
{viewName} {viewName}
</StyledViewSection> </StyledViewSection>
<StyledFilters> <StyledFilters>
<DropdownButton label="Filter" options={[]} isActive={false} /> <DropdownButton
label="Filter"
options={[]}
isActive={false}
></DropdownButton>
<SortDropdownButton <SortDropdownButton
setSorts={setSorts} setSorts={setSorts}
sorts={sorts} sorts={sorts}
sortsAvailable={sortsAvailable} sortsAvailable={sortsAvailable}
/> />
<DropdownButton label="Settings" options={[]} isActive={false} /> <DropdownButton
label="Settings"
options={[]}
isActive={false}
></DropdownButton>
</StyledFilters> </StyledFilters>
</StyledTableHeader> </StyledTableHeader>
{sorts.length > 0 && ( {sorts.length > 0 && (