Skip to content

Commit

Permalink
feat(ui): simpler dnd indicator for right panel tabs
Browse files Browse the repository at this point in the history
We can use the drop overlay component directly for this, without needing to add it as a `noop` dnd target.

Other changes:
- The `label` prop is now used to conditionally render the label - every drop target provides its own label, so this doesn't break anything.
- Add `withBackdrop` prop to control whether we apply the dimmed drop target effect.
  • Loading branch information
psychedelicious committed Oct 16, 2024
1 parent c222d43 commit f0f357f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 17 deletions.
29 changes: 15 additions & 14 deletions invokeai/frontend/web/src/common/components/IAIDropOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { Flex, Text } from '@invoke-ai/ui-library';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

type Props = {
isOver: boolean;
label?: string;
withBackdrop?: boolean;
};

const IAIDropOverlay = (props: Props) => {
const { t } = useTranslation();
const { isOver, label = t('gallery.drop') } = props;
const { isOver, label, withBackdrop = true } = props;
return (
<Flex position="absolute" top={0} right={0} bottom={0} left={0}>
<Flex
Expand All @@ -20,7 +19,7 @@ const IAIDropOverlay = (props: Props) => {
left={0}
w="full"
h="full"
bg="base.900"
bg={withBackdrop ? 'base.900' : 'transparent'}
opacity={0.7}
borderRadius="base"
alignItems="center"
Expand All @@ -45,16 +44,18 @@ const IAIDropOverlay = (props: Props) => {
alignItems="center"
justifyContent="center"
>
<Text
fontSize="lg"
fontWeight="semibold"
color={isOver ? 'invokeYellow.300' : 'base.500'}
transitionProperty="common"
transitionDuration="0.1s"
textAlign="center"
>
{label}
</Text>
{label && (
<Text
fontSize="lg"
fontWeight="semibold"
color={isOver ? 'invokeYellow.300' : 'base.500'}
transitionProperty="common"
transitionDuration="0.1s"
textAlign="center"
>
{label}
</Text>
)}
</Flex>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useDndContext } from '@dnd-kit/core';
import { Box, Button, Spacer, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIDropOverlay from 'common/components/IAIDropOverlay';
import { CanvasLayersPanelContent } from 'features/controlLayers/components/CanvasLayersPanelContent';
import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
import { selectEntityCountActive } from 'features/controlLayers/store/selectors';
Expand All @@ -9,7 +10,7 @@ import { useImageViewer } from 'features/gallery/components/ImageViewer/useImage
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
import { selectActiveTabCanvasRightPanel } from 'features/ui/store/uiSelectors';
import { activeTabCanvasRightPanelChanged } from 'features/ui/store/uiSlice';
import { memo, useCallback, useMemo, useRef } from 'react';
import { memo, useCallback, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';

export const CanvasRightPanel = memo(() => {
Expand Down Expand Up @@ -78,12 +79,15 @@ CanvasRightPanel.displayName = 'CanvasRightPanel';

const PanelTabs = memo(() => {
const { t } = useTranslation();
const activeTab = useAppSelector(selectActiveTabCanvasRightPanel);
const activeEntityCount = useAppSelector(selectEntityCountActive);
const tabTimeout = useRef<number | null>(null);
const dndCtx = useDndContext();
const dispatch = useAppDispatch();
const [mouseOverTab, setMouseOverTab] = useState<'layers' | 'gallery' | null>(null);

const onOnMouseOverLayersTab = useCallback(() => {
setMouseOverTab('layers');
tabTimeout.current = window.setTimeout(() => {
if (dndCtx.active) {
dispatch(activeTabCanvasRightPanelChanged('layers'));
Expand All @@ -92,6 +96,7 @@ const PanelTabs = memo(() => {
}, [dndCtx.active, dispatch]);

const onOnMouseOverGalleryTab = useCallback(() => {
setMouseOverTab('gallery');
tabTimeout.current = window.setTimeout(() => {
if (dndCtx.active) {
dispatch(activeTabCanvasRightPanelChanged('gallery'));
Expand All @@ -100,6 +105,7 @@ const PanelTabs = memo(() => {
}, [dndCtx.active, dispatch]);

const onMouseOut = useCallback(() => {
setMouseOverTab(null);
if (tabTimeout.current) {
clearTimeout(tabTimeout.current);
}
Expand All @@ -118,9 +124,17 @@ const PanelTabs = memo(() => {
<Box as="span" w="full">
{layersTabLabel}
</Box>
{dndCtx.active && activeTab !== 'layers' && (
<IAIDropOverlay isOver={mouseOverTab === 'layers'} withBackdrop={false} />
)}
</Tab>
<Tab position="relative" onMouseOver={onOnMouseOverGalleryTab} onMouseOut={onMouseOut}>
{t('gallery.gallery')}
<Tab position="relative" onMouseOver={onOnMouseOverGalleryTab} onMouseOut={onMouseOut} w={32}>
<Box as="span" w="full">
{t('gallery.gallery')}
</Box>
{dndCtx.active && activeTab !== 'gallery' && (
<IAIDropOverlay isOver={mouseOverTab === 'gallery'} withBackdrop={false} />
)}
</Tab>
</>
);
Expand Down

0 comments on commit f0f357f

Please sign in to comment.