1880 Refactored Dropdown components (#1884)

* updated DropdownButton props

* refactoring in progress

* working but layout is wrong

* fixed bug

* wip on ColumnHeadWithDropdown

* fix bug

* fix bug

* remove unused styled component

* fix z-index bug

* add an optional argument to DropdownMenu to control the offset of the menu

* add an optional argument to DropdownMenu to control the offset of the menu

* modify files after PR comments

* clean the way the offset is handled

* fix lint
This commit is contained in:
bosiraphael
2023-10-05 18:11:54 +02:00
committed by GitHub
parent b8282e6789
commit 922f8eca0e
23 changed files with 213 additions and 182 deletions

View File

@ -1,16 +1,16 @@
import { LightButton } from '@/ui/button/components/LightButton';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { useDropdown } from '@/ui/dropdown/hooks/useDropdown';
import { IconPlus } from '@/ui/icon';
import { FilterDropdownId } from '../constants/FilterDropdownId';
export const AddFilterFromDropdownButton = () => {
const { toggleDropdownButton } = useDropdownButton({
const { toggleDropdown } = useDropdown({
dropdownId: FilterDropdownId,
});
const handleClick = () => {
toggleDropdownButton();
toggleDropdown();
};
return (

View File

@ -1,5 +1,5 @@
import { StyledHeaderDropdownButton } from '@/ui/dropdown/components/StyledHeaderDropdownButton';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { useDropdown } from '@/ui/dropdown/hooks/useDropdown';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { FilterDropdownId } from '../constants/FilterDropdownId';
@ -12,7 +12,7 @@ import { selectedOperandInDropdownScopedState } from '../states/selectedOperandI
export const MultipleFiltersButton = () => {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const { isDropdownButtonOpen, toggleDropdownButton } = useDropdownButton({
const { isDropdownOpen, toggleDropdown } = useDropdown({
dropdownId: FilterDropdownId,
});
@ -44,13 +44,13 @@ export const MultipleFiltersButton = () => {
};
const handleClick = () => {
toggleDropdownButton();
toggleDropdown();
resetState();
};
return (
<StyledHeaderDropdownButton
isUnfolded={isDropdownButtonOpen}
isUnfolded={isDropdownOpen}
onClick={handleClick}
>
Filter

View File

@ -1,10 +1,10 @@
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { FilterDropdownId } from '../constants/FilterDropdownId';
import { MultipleFiltersButton } from './MultipleFiltersButton';
import { MultipleFiltersDropdownContent } from './MultipleFiltersDropdownContent';
import { ViewBarDropdownButton } from './ViewBarDropdownButton';
type MultipleFiltersDropdownButtonProps = {
hotkeyScope: HotkeyScope;
@ -14,9 +14,9 @@ export const MultipleFiltersDropdownButton = ({
hotkeyScope,
}: MultipleFiltersDropdownButtonProps) => {
return (
<DropdownButton
<ViewBarDropdownButton
dropdownId={FilterDropdownId}
buttonComponents={<MultipleFiltersButton />}
buttonComponent={<MultipleFiltersButton />}
dropdownComponents={<MultipleFiltersDropdownContent />}
dropdownHotkeyScope={hotkeyScope}
/>

View File

@ -2,12 +2,11 @@ import { useCallback, useState } from 'react';
import { produce } from 'immer';
import { LightButton } from '@/ui/button/components/LightButton';
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { useDropdown } from '@/ui/dropdown/hooks/useDropdown';
import { IconChevronDown } from '@/ui/icon';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
@ -20,6 +19,8 @@ import { sortsScopedState } from '../states/sortsScopedState';
import { SortDefinition } from '../types/SortDefinition';
import { SORT_DIRECTIONS, SortDirection } from '../types/SortDirection';
import { ViewBarDropdownButton } from './ViewBarDropdownButton';
export type SortDropdownButtonProps = {
hotkeyScope: HotkeyScope;
isPrimaryButton?: boolean;
@ -53,17 +54,17 @@ export const SortDropdownButton = ({
const isSortSelected = sorts.length > 0;
const { toggleDropdownButton } = useDropdownButton({
const { toggleDropdown } = useDropdown({
dropdownId: SortDropdownId,
});
const handleButtonClick = () => {
toggleDropdownButton();
toggleDropdown();
resetState();
};
const handleAddSort = (selectedSortDefinition: SortDefinition) => {
toggleDropdownButton();
toggleDropdown();
setSorts(
produce(sorts, (existingSortsDraft) => {
@ -90,10 +91,10 @@ export const SortDropdownButton = ({
};
return (
<DropdownButton
<ViewBarDropdownButton
dropdownId={SortDropdownId}
dropdownHotkeyScope={hotkeyScope}
buttonComponents={
buttonComponent={
<LightButton
title="Sort"
active={isSortSelected}
@ -140,6 +141,6 @@ export const SortDropdownButton = ({
</StyledDropdownMenu>
}
onClose={handleDropdownButtonClose}
></DropdownButton>
></ViewBarDropdownButton>
);
};

View File

@ -1,6 +1,6 @@
import { ReactNode } from 'react';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { useDropdown } from '@/ui/dropdown/hooks/useDropdown';
import { TopBar } from '@/ui/top-bar/TopBar';
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
@ -23,7 +23,7 @@ export const ViewBar = ({
optionsDropdownButton,
optionsDropdownKey,
}: ViewBarProps) => {
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
const { openDropdown: openOptionsDropdownButton } = useDropdown({
dropdownId: optionsDropdownKey,
});

View File

@ -0,0 +1,47 @@
import { Keys } from 'react-hotkeys-hook';
import { Placement } from '@floating-ui/react';
import { DropdownMenu } from '@/ui/dropdown/components/DropdownMenu';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
type DropdownButtonProps = {
buttonComponent: JSX.Element | JSX.Element[];
dropdownComponents: JSX.Element | JSX.Element[];
dropdownId: string;
hotkey?: {
key: Keys;
scope: string;
};
dropdownHotkeyScope: HotkeyScope;
dropdownPlacement?: Placement;
onClickOutside?: () => void;
onClose?: () => void;
onOpen?: () => void;
};
export const ViewBarDropdownButton = ({
buttonComponent,
dropdownComponents,
dropdownId,
hotkey,
dropdownHotkeyScope,
dropdownPlacement = 'bottom-end',
onClickOutside,
onClose,
onOpen,
}: DropdownButtonProps) => {
return (
<DropdownMenu
clickableComponent={buttonComponent}
dropdownComponents={dropdownComponents}
dropdownId={dropdownId}
hotkey={hotkey}
dropdownHotkeyScope={dropdownHotkeyScope}
dropdownOffset={{ x: 0, y: 8 }}
dropdownPlacement={dropdownPlacement}
onClickOutside={onClickOutside}
onClose={onClose}
onOpen={onOpen}
/>
);
};

View File

@ -8,12 +8,11 @@ import {
useSetRecoilState,
} from 'recoil';
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { StyledDropdownButtonContainer } from '@/ui/dropdown/components/StyledDropdownButtonContainer';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { useDropdown } from '@/ui/dropdown/hooks/useDropdown';
import {
IconChevronDown,
IconList,
@ -42,6 +41,8 @@ import { ViewsDropdownId } from '../constants/ViewsDropdownId';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { useRemoveView } from '../hooks/useRemoveView';
import { ViewBarDropdownButton } from './ViewBarDropdownButton';
const StyledBoldDropdownMenuItemsContainer = styled(
StyledDropdownMenuItemsContainer,
)`
@ -105,10 +106,9 @@ export const ViewsDropdownButton = ({
entityCountInCurrentViewState as RecoilValueReadOnly<number>,
);
const { isDropdownButtonOpen, closeDropdownButton, toggleDropdownButton } =
useDropdownButton({
dropdownId: ViewsDropdownId,
});
const { isDropdownOpen, closeDropdown } = useDropdown({
dropdownId: ViewsDropdownId,
});
const setViewEditMode = useSetRecoilState(viewEditModeState);
@ -127,15 +127,15 @@ export const ViewsDropdownButton = ({
set(filtersScopedState(recoilScopeId), savedFilters);
set(sortsScopedState(recoilScopeId), savedSorts);
set(currentViewIdScopedState(recoilScopeId), viewId);
closeDropdownButton();
closeDropdown();
},
[onViewSelect, recoilScopeId, closeDropdownButton],
[onViewSelect, recoilScopeId, closeDropdown],
);
const handleAddViewButtonClick = () => {
setViewEditMode({ mode: 'create', viewId: undefined });
onViewEditModeChange?.();
closeDropdownButton();
closeDropdown();
};
const handleEditViewButtonClick = (
@ -145,7 +145,7 @@ export const ViewsDropdownButton = ({
event.stopPropagation();
setViewEditMode({ mode: 'edit', viewId });
onViewEditModeChange?.();
closeDropdownButton();
closeDropdown();
};
const { removeView } = useRemoveView();
@ -157,22 +157,15 @@ export const ViewsDropdownButton = ({
event.stopPropagation();
await removeView(viewId);
closeDropdownButton();
};
const handleViewButtonClick = () => {
toggleDropdownButton();
closeDropdown();
};
return (
<DropdownButton
<ViewBarDropdownButton
dropdownId={ViewsDropdownId}
dropdownHotkeyScope={hotkeyScope}
buttonComponents={
<StyledDropdownButtonContainer
isUnfolded={isDropdownButtonOpen}
onClick={handleViewButtonClick}
>
buttonComponent={
<StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
<StyledViewIcon size={theme.icon.size.md} />
<StyledViewName>
{currentView?.name || defaultViewName}