Skip to content

Commit

Permalink
fixes menu action behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
agnlez committed Nov 22, 2023
1 parent 427ee4d commit 76082b2
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 43 deletions.
2 changes: 1 addition & 1 deletion app/hooks/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export function useSelectedFeatures(
max: amountMax,
},
color: featureColorQueryState
? featureColorQueryState.data.find(({ id }) => featureId === id)?.color
? featureColorQueryState?.data?.find(({ id }) => featureId === id)?.color
: null,

// SPLIT
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useCallback, useRef, useState } from 'react';

import { HiDotsHorizontal } from 'react-icons/hi';

import Checkbox from 'components/forms/checkbox';
Expand All @@ -18,6 +20,12 @@ const RowItem = ({
ActionsComponent,
}: RowItem) => {
const { id, name, scenarios, tag, isVisibleOnMap, isCustom } = item;
const [isMenuOpen, setIsMenuOpen] = useState(false);
const buttonRef = useRef<HTMLButtonElement>(null);

const onDismissMenu = useCallback(() => {
setIsMenuOpen(false);
}, []);

return (
<tr key={id} className="flex w-full align-top">
Expand Down Expand Up @@ -70,25 +78,35 @@ const RowItem = ({
/>
</button>

<Popover modal>
<Popover open={isMenuOpen}>
<PopoverTrigger asChild>
<button
type="button"
className={cn({
'h-5 w-5': true,
invisible: !isCustom,
})}
ref={buttonRef}
onClick={() => {
setIsMenuOpen((prevState) => !prevState);
}}
>
<HiDotsHorizontal className="h-4 w-4 text-white" />
<HiDotsHorizontal className="pointer-events-none h-4 w-4 text-white" />
</button>
</PopoverTrigger>
<PopoverContent
hideWhenDetached
className="w-auto rounded-2xl border-transparent p-0"
side="bottom"
sideOffset={5}
align="start"
onInteractOutside={(evt) => {
if (evt.target !== buttonRef.current) {
setIsMenuOpen(false);
}
}}
>
<ActionsComponent item={item} />
<ActionsComponent item={item} onDismissMenu={onDismissMenu} />
</PopoverContent>
</Popover>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@ export type RowItem = {
selectedIds: string[];
onSelectRow: (evt: ChangeEvent<HTMLInputElement>) => void;
onToggleSeeOnMap: (id: string) => void;
ActionsComponent: ({ item }: { item: DataItem }) => JSX.Element;
ActionsComponent: ({
item,
onDismissMenu,
}: {
item: DataItem;
onDismissMenu: () => void;
}) => JSX.Element;
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { ComponentProps, useCallback, useState } from 'react';

import Icon from 'components/icon';
import Modal from 'components/modal/component';
Expand All @@ -9,33 +9,33 @@ import { cn } from 'utils/cn';
import DELETE_SVG from 'svgs/ui/new-layout/delete.svg?sprite';
import TAG_SVG from 'svgs/ui/tag.svg?sprite';

import RowItem from '../../components/inventory-table/row-item';

const BUTTON_CLASSES =
'flex items-center px-4 py-2 w-full text-sm cursor-pointer bg-gray-800 hover:bg-gray-600 transition transition-colors space-x-2 group';

const ICON_CLASSES = 'h-5 w-5 text-gray-100 group-hover:text-white';

const ActionsMenu = ({
item,
}: {
item: {
id: string;
name: string;
scenarios: number;
tag: string;
custom: boolean;
};
}): JSX.Element => {
const isDeletable = !item.custom && !item.scenarios;
onDismissMenu,
}: Parameters<ComponentProps<typeof RowItem>['ActionsComponent']>[0]): JSX.Element => {
const isDeletable = !item.isCustom && !item.scenarios;

// item.isCustom && !item.scenarioUsageCount
const [modalState, setModalState] = useState<{ edit: boolean; delete: boolean }>({
edit: false,
delete: false,
});

const handleModal = useCallback((modalKey: keyof typeof modalState, isVisible: boolean) => {
setModalState((prevState) => ({ ...prevState, [modalKey]: isVisible }));
}, []);
const handleModal = useCallback(
(modalKey: keyof typeof modalState, isVisible: boolean) => {
setModalState((prevState) => {
if (!isVisible) onDismissMenu();
return { ...prevState, [modalKey]: isVisible };
});
},
[onDismissMenu]
);

return (
<ul className="rounded-2xl border-gray-600">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useCallback, useState } from 'react';
import { ComponentProps, useCallback, useState } from 'react';

import Icon from 'components/icon';
import Modal from 'components/modal/component';
import { type DataItem } from 'layout/project/sidebar/project/inventory-panel/components/inventory-table';
import RowItem from 'layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item';
import DeleteModal from 'layout/project/sidebar/project/inventory-panel/features/modals/delete';
import EditModal from 'layout/project/sidebar/project/inventory-panel/features/modals/edit';
import { cn } from 'utils/cn';
Expand All @@ -19,24 +19,35 @@ const ICON_CLASSES = 'h-5 w-5 text-gray-100 group-hover:text-white';

const ICON_DISABLED_CLASSES = 'text-gray-700';

const ActionsMenu = ({ item }: { item: DataItem }): JSX.Element => {
const ActionsMenu = ({
item,
onDismissMenu,
}: Parameters<ComponentProps<typeof RowItem>['ActionsComponent']>[0]): JSX.Element => {
const isDeletable = !item.isCustom || !item.scenarios;

const [modalState, setModalState] = useState<{ edit: boolean; delete: boolean }>({
edit: false,
delete: false,
});

const handleModal = useCallback((modalKey: keyof typeof modalState, isVisible: boolean) => {
setModalState((prevState) => ({ ...prevState, [modalKey]: isVisible }));
}, []);
const handleModal = useCallback(
(modalKey: keyof typeof modalState, isVisible: boolean) => {
setModalState((prevState) => {
if (!isVisible) onDismissMenu();
return { ...prevState, [modalKey]: isVisible };
});
},
[onDismissMenu]
);

return (
<ul className="rounded-2xl border-gray-600">
<li>
<button
type="button"
onClick={() => handleModal('edit', true)}
onClick={() => {
handleModal('edit', true);
}}
className={cn({
[BUTTON_CLASSES]: true,
'rounded-t-2xl': true,
Expand All @@ -50,7 +61,9 @@ const ActionsMenu = ({ item }: { item: DataItem }): JSX.Element => {
title="All features"
open={modalState.edit}
size="narrow"
onDismiss={() => handleModal('edit', false)}
onDismiss={() => {
handleModal('edit', false);
}}
>
<EditModal featureId={item.id} handleModal={handleModal} />
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const InventoryPanelFeatures = ({ noData: noDataMessage }: { noData: string }):
{
select: ({ data }) => {
return data?.map((feature) => {
const { color } = featureColorQueryState.data.find(({ id }) => feature.id === id) || {};
const { color } = featureColorQueryState?.data?.find(({ id }) => feature.id === id) || {};

return {
id: feature.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { ComponentProps, useCallback, useState } from 'react';

import Icon from 'components/icon';
import Modal from 'components/modal/component';
Expand All @@ -9,32 +9,33 @@ import { cn } from 'utils/cn';
import DELETE_SVG from 'svgs/ui/new-layout/delete.svg?sprite';
import TAG_SVG from 'svgs/ui/tag.svg?sprite';

import RowItem from '../../components/inventory-table/row-item';

const BUTTON_CLASSES =
'flex items-center px-4 py-2 w-full text-sm cursor-pointer bg-gray-800 hover:bg-gray-600 transition transition-colors space-x-2 group';

const ICON_CLASSES = 'h-5 w-5 text-gray-100 group-hover:text-white';

const ActionsMenu = ({
item,
}: {
item: {
id: string;
name: string;
scenarios: number;
tag: string;
custom: boolean;
};
}): JSX.Element => {
const isDeletable = !item.custom && !item.scenarios;
onDismissMenu,
}: Parameters<ComponentProps<typeof RowItem>['ActionsComponent']>[0]): JSX.Element => {
const isDeletable = !item.isCustom && !item.scenarios;

const [modalState, setModalState] = useState<{ edit: boolean; delete: boolean }>({
edit: false,
delete: false,
});

const handleModal = useCallback((modalKey: keyof typeof modalState, isVisible: boolean) => {
setModalState((prevState) => ({ ...prevState, [modalKey]: isVisible }));
}, []);
const handleModal = useCallback(
(modalKey: keyof typeof modalState, isVisible: boolean) => {
setModalState((prevState) => {
if (!isVisible) onDismissMenu();
return { ...prevState, [modalKey]: isVisible };
});
},
[onDismissMenu]
);

return (
<ul className="rounded-2xl border-gray-600">
Expand Down

0 comments on commit 76082b2

Please sign in to comment.