feat(ui): add layerwrapper component

This commit is contained in:
psychedelicious 2024-05-02 20:52:49 +10:00 committed by Kent Keirsey
parent d55ea318ec
commit d67480d92c
4 changed files with 73 additions and 62 deletions

View File

@ -5,6 +5,7 @@ import { LayerDeleteButton } from 'features/controlLayers/components/LayerCommon
import { LayerMenu } from 'features/controlLayers/components/LayerCommon/LayerMenu'; import { LayerMenu } from 'features/controlLayers/components/LayerCommon/LayerMenu';
import { LayerTitle } from 'features/controlLayers/components/LayerCommon/LayerTitle'; import { LayerTitle } from 'features/controlLayers/components/LayerCommon/LayerTitle';
import { LayerVisibilityToggle } from 'features/controlLayers/components/LayerCommon/LayerVisibilityToggle'; import { LayerVisibilityToggle } from 'features/controlLayers/components/LayerCommon/LayerVisibilityToggle';
import { LayerWrapper } from 'features/controlLayers/components/LayerCommon/LayerWrapper';
import { layerSelected, selectCALayerOrThrow } from 'features/controlLayers/store/controlLayersSlice'; import { layerSelected, selectCALayerOrThrow } from 'features/controlLayers/store/controlLayersSlice';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
@ -17,22 +18,14 @@ type Props = {
export const CALayer = memo(({ layerId }: Props) => { export const CALayer = memo(({ layerId }: Props) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const isSelected = useAppSelector((s) => selectCALayerOrThrow(s.controlLayers.present, layerId).isSelected); const isSelected = useAppSelector((s) => selectCALayerOrThrow(s.controlLayers.present, layerId).isSelected);
const onClickCapture = useCallback(() => { const onClick = useCallback(() => {
// Must be capture so that the layer is selected before deleting/resetting/etc // Must be capture so that the layer is selected before deleting/resetting/etc
dispatch(layerSelected(layerId)); dispatch(layerSelected(layerId));
}, [dispatch, layerId]); }, [dispatch, layerId]);
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true }); const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true });
return ( return (
<Flex <LayerWrapper onClick={onClick} borderColor={isSelected ? 'base.400' : 'base.800'}>
gap={2}
onClickCapture={onClickCapture}
bg={isSelected ? 'base.400' : 'base.800'}
px={2}
borderRadius="base"
py="1px"
>
<Flex flexDir="column" w="full" bg="base.850" borderRadius="base">
<Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}> <Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}>
<LayerVisibilityToggle layerId={layerId} /> <LayerVisibilityToggle layerId={layerId} />
<LayerTitle type="control_adapter_layer" /> <LayerTitle type="control_adapter_layer" />
@ -46,8 +39,7 @@ export const CALayer = memo(({ layerId }: Props) => {
<CALayerControlAdapterWrapper layerId={layerId} /> <CALayerControlAdapterWrapper layerId={layerId} />
</Flex> </Flex>
)} )}
</Flex> </LayerWrapper>
</Flex>
); );
}); });

View File

@ -3,6 +3,7 @@ import { IPALayerIPAdapterWrapper } from 'features/controlLayers/components/IPAL
import { LayerDeleteButton } from 'features/controlLayers/components/LayerCommon/LayerDeleteButton'; import { LayerDeleteButton } from 'features/controlLayers/components/LayerCommon/LayerDeleteButton';
import { LayerTitle } from 'features/controlLayers/components/LayerCommon/LayerTitle'; import { LayerTitle } from 'features/controlLayers/components/LayerCommon/LayerTitle';
import { LayerVisibilityToggle } from 'features/controlLayers/components/LayerCommon/LayerVisibilityToggle'; import { LayerVisibilityToggle } from 'features/controlLayers/components/LayerCommon/LayerVisibilityToggle';
import { LayerWrapper } from 'features/controlLayers/components/LayerCommon/LayerWrapper';
import { memo } from 'react'; import { memo } from 'react';
type Props = { type Props = {
@ -12,8 +13,7 @@ type Props = {
export const IPALayer = memo(({ layerId }: Props) => { export const IPALayer = memo(({ layerId }: Props) => {
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true }); const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true });
return ( return (
<Flex gap={2} bg="base.800" borderRadius="base" p="1px" px={2}> <LayerWrapper borderColor="base.800">
<Flex flexDir="column" w="full" bg="base.850" borderRadius="base">
<Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}> <Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}>
<LayerVisibilityToggle layerId={layerId} /> <LayerVisibilityToggle layerId={layerId} />
<LayerTitle type="ip_adapter_layer" /> <LayerTitle type="ip_adapter_layer" />
@ -25,8 +25,7 @@ export const IPALayer = memo(({ layerId }: Props) => {
<IPALayerIPAdapterWrapper layerId={layerId} /> <IPALayerIPAdapterWrapper layerId={layerId} />
</Flex> </Flex>
)} )}
</Flex> </LayerWrapper>
</Flex>
); );
}); });

View File

@ -0,0 +1,21 @@
import type { ChakraProps } from '@invoke-ai/ui-library';
import { Flex } from '@invoke-ai/ui-library';
import type { PropsWithChildren } from 'react';
import { memo } from 'react';
type Props = PropsWithChildren<{
onClick?: () => void;
borderColor: ChakraProps['bg'];
}>;
export const LayerWrapper = memo(({ onClick, borderColor, children }: Props) => {
return (
<Flex gap={2} onClick={onClick} bg={borderColor} px={2} borderRadius="base" py="1px">
<Flex flexDir="column" w="full" bg="base.850" borderRadius="base">
{children}
</Flex>
</Flex>
);
});
LayerWrapper.displayName = 'LayerWrapper';

View File

@ -7,6 +7,7 @@ import { LayerDeleteButton } from 'features/controlLayers/components/LayerCommon
import { LayerMenu } from 'features/controlLayers/components/LayerCommon/LayerMenu'; import { LayerMenu } from 'features/controlLayers/components/LayerCommon/LayerMenu';
import { LayerTitle } from 'features/controlLayers/components/LayerCommon/LayerTitle'; import { LayerTitle } from 'features/controlLayers/components/LayerCommon/LayerTitle';
import { LayerVisibilityToggle } from 'features/controlLayers/components/LayerCommon/LayerVisibilityToggle'; import { LayerVisibilityToggle } from 'features/controlLayers/components/LayerCommon/LayerVisibilityToggle';
import { LayerWrapper } from 'features/controlLayers/components/LayerCommon/LayerWrapper';
import { import {
isRegionalGuidanceLayer, isRegionalGuidanceLayer,
layerSelected, layerSelected,
@ -52,8 +53,7 @@ export const RGLayer = memo(({ layerId }: Props) => {
dispatch(layerSelected(layerId)); dispatch(layerSelected(layerId));
}, [dispatch, layerId]); }, [dispatch, layerId]);
return ( return (
<Flex gap={2} onClick={onClick} bg={isSelected ? color : 'base.800'} px={2} borderRadius="base" py="1px"> <LayerWrapper onClick={onClick} borderColor={isSelected ? color : 'base.800'}>
<Flex flexDir="column" w="full" bg="base.850" borderRadius="base">
<Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}> <Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}>
<LayerVisibilityToggle layerId={layerId} /> <LayerVisibilityToggle layerId={layerId} />
<LayerTitle type="regional_guidance_layer" /> <LayerTitle type="regional_guidance_layer" />
@ -76,8 +76,7 @@ export const RGLayer = memo(({ layerId }: Props) => {
{hasIPAdapters && <RGLayerIPAdapterList layerId={layerId} />} {hasIPAdapters && <RGLayerIPAdapterList layerId={layerId} />}
</Flex> </Flex>
)} )}
</Flex> </LayerWrapper>
</Flex>
); );
}); });