From 024759a0fc8db360b2cc76bdca94e6bc76d6fbb6 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:22:03 +1000 Subject: [PATCH] feat(ui): tweaked entity & group selection styles --- .../components/ControlAdapter/CA.tsx | 2 +- .../ControlAdapter/CAEntityHeader.tsx | 5 +++-- .../components/ControlAdapter/CAEntityList.tsx | 18 ++++++------------ .../controlLayers/components/IPAdapter/IPA.tsx | 2 +- .../components/IPAdapter/IPAEntityList.tsx | 15 ++++++--------- .../components/IPAdapter/IPAHeader.tsx | 5 +++-- .../components/InpaintMask/IM.tsx | 2 +- .../components/InpaintMask/IMHeader.tsx | 5 +++-- .../controlLayers/components/Layer/Layer.tsx | 2 +- .../components/Layer/LayerEntityList.tsx | 15 ++++++--------- .../components/Layer/LayerHeader.tsx | 5 +++-- .../components/RegionalGuidance/RG.tsx | 2 +- .../RegionalGuidance/RGEntityList.tsx | 18 ++++++------------ .../components/RegionalGuidance/RGHeader.tsx | 5 +++-- .../common/CanvasEntityContainer.tsx | 16 +++++----------- .../common/CanvasEntityGroupTitle.tsx | 17 +++++++++++++++++ .../components/common/CanvasEntityTitle.tsx | 5 +++-- 17 files changed, 69 insertions(+), 70 deletions(-) create mode 100644 invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityGroupTitle.tsx diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CA.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CA.tsx index f58e37b275..9bb6dff791 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CA.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CA.tsx @@ -20,7 +20,7 @@ export const CA = memo(({ id }: Props) => { return ( - + {isOpen && } ); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityHeader.tsx index fe49d9953b..2eef6f5cb6 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityHeader.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityHeader.tsx @@ -13,10 +13,11 @@ import { useTranslation } from 'react-i18next'; type Props = { id: string; + isSelected: boolean; onToggleVisibility: () => void; }; -export const CAHeader = memo(({ id, onToggleVisibility }: Props) => { +export const CAHeader = memo(({ id, isSelected, onToggleVisibility }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const isEnabled = useAppSelector((s) => selectCAOrThrow(s.canvasV2, id).isEnabled); @@ -30,7 +31,7 @@ export const CAHeader = memo(({ id, onToggleVisibility }: Props) => { return ( - + diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityList.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityList.tsx index 01c1310b75..bc6d5bbe55 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityList.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlAdapter/CAEntityList.tsx @@ -1,6 +1,6 @@ -import { Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; +import { CanvasEntityGroupTitle } from 'features/controlLayers/components/common/CanvasEntityGroupTitle'; import { CA } from 'features/controlLayers/components/ControlAdapter/CA'; import { mapId } from 'features/controlLayers/konva/util'; import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; @@ -13,10 +13,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) = export const CAEntityList = memo(() => { const { t } = useTranslation(); - const isTypeSelected = useAppSelector((s) => - Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'control_adapter') - ); - + const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'control_adapter')); const caIds = useAppSelector(selectEntityIds); if (caIds.length === 0) { @@ -26,13 +23,10 @@ export const CAEntityList = memo(() => { if (caIds.length > 0) { return ( <> - - {t('controlLayers.controlAdapters_withCount', { count: caIds.length })} - + {caIds.map((id) => ( ))} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPA.tsx b/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPA.tsx index 69e88c9d8c..8281cadc32 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPA.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPA.tsx @@ -20,7 +20,7 @@ export const IPA = memo(({ id }: Props) => { return ( - + {isOpen && } ); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAEntityList.tsx b/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAEntityList.tsx index 01f1eda0e5..5e04bc6162 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAEntityList.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAEntityList.tsx @@ -1,7 +1,7 @@ /* eslint-disable i18next/no-literal-string */ -import { Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; +import { CanvasEntityGroupTitle } from 'features/controlLayers/components/common/CanvasEntityGroupTitle'; import { IPA } from 'features/controlLayers/components/IPAdapter/IPA'; import { mapId } from 'features/controlLayers/konva/util'; import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; @@ -14,7 +14,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) = export const IPAEntityList = memo(() => { const { t } = useTranslation(); - const isTypeSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'ip_adapter')); + const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'ip_adapter')); const ipaIds = useAppSelector(selectEntityIds); if (ipaIds.length === 0) { @@ -24,13 +24,10 @@ export const IPAEntityList = memo(() => { if (ipaIds.length > 0) { return ( <> - - {t('controlLayers.ipAdapters_withCount', { count: ipaIds.length })} - + {ipaIds.map((id) => ( ))} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAHeader.tsx index ec56c81b91..81e63929e8 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAHeader.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/IPAdapter/IPAHeader.tsx @@ -11,10 +11,11 @@ import { useTranslation } from 'react-i18next'; type Props = { id: string; + isSelected: boolean; onToggleVisibility: () => void; }; -export const IPAHeader = memo(({ id, onToggleVisibility }: Props) => { +export const IPAHeader = memo(({ id, isSelected, onToggleVisibility }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const isEnabled = useAppSelector((s) => selectIPAOrThrow(s.canvasV2, id).isEnabled); @@ -28,7 +29,7 @@ export const IPAHeader = memo(({ id, onToggleVisibility }: Props) => { return ( - + diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IM.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IM.tsx index 544fece75b..55a332270d 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IM.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IM.tsx @@ -17,7 +17,7 @@ export const IM = memo(() => { }, [dispatch]); return ( - + {isOpen && } ); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IMHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IMHeader.tsx index 1102e056f3..888c5b1eb3 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IMHeader.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/IMHeader.tsx @@ -11,10 +11,11 @@ import { useTranslation } from 'react-i18next'; import { IMMaskFillColorPicker } from './IMMaskFillColorPicker'; type Props = { + isSelected: boolean; onToggleVisibility: () => void; }; -export const IMHeader = memo(({ onToggleVisibility }: Props) => { +export const IMHeader = memo(({ isSelected, onToggleVisibility }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const isEnabled = useAppSelector((s) => s.canvasV2.inpaintMask.isEnabled); @@ -25,7 +26,7 @@ export const IMHeader = memo(({ onToggleVisibility }: Props) => { return ( - + diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Layer/Layer.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Layer/Layer.tsx index 5fda4e72b4..1e2b6fdf1d 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/Layer/Layer.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/Layer/Layer.tsx @@ -26,7 +26,7 @@ export const Layer = memo(({ id }: Props) => { return ( - + {isOpen && } diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerEntityList.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerEntityList.tsx index 92f3174b7a..1dae90ba0b 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerEntityList.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerEntityList.tsx @@ -1,6 +1,6 @@ -import { Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; +import { CanvasEntityGroupTitle } from 'features/controlLayers/components/common/CanvasEntityGroupTitle'; import { Layer } from 'features/controlLayers/components/Layer/Layer'; import { mapId } from 'features/controlLayers/konva/util'; import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; @@ -13,7 +13,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) = export const LayerEntityList = memo(() => { const { t } = useTranslation(); - const isTypeSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'layer')); + const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'layer')); const layerIds = useAppSelector(selectEntityIds); if (layerIds.length === 0) { @@ -23,13 +23,10 @@ export const LayerEntityList = memo(() => { if (layerIds.length > 0) { return ( <> - - {t('controlLayers.layers_withCount', { count: layerIds.length })} - + {layerIds.map((id) => ( ))} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerHeader.tsx index 53a8d0dbfa..b53ca7f275 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerHeader.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/Layer/LayerHeader.tsx @@ -14,10 +14,11 @@ import { LayerOpacity } from './LayerOpacity'; type Props = { id: string; + isSelected: boolean; onToggleVisibility: () => void; }; -export const LayerHeader = memo(({ id, onToggleVisibility }: Props) => { +export const LayerHeader = memo(({ id, isSelected, onToggleVisibility }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const isEnabled = useAppSelector((s) => selectLayerOrThrow(s.canvasV2, id).isEnabled); @@ -35,7 +36,7 @@ export const LayerHeader = memo(({ id, onToggleVisibility }: Props) => { return ( - + diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RG.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RG.tsx index 12297ab5a1..fe923169cb 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RG.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RG.tsx @@ -22,7 +22,7 @@ export const RG = memo(({ id }: Props) => { }, [dispatch, id]); return ( - + {isOpen && } ); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGEntityList.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGEntityList.tsx index 6b1b38ac89..a00fea3e0a 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGEntityList.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGEntityList.tsx @@ -1,6 +1,6 @@ -import { Text } from '@invoke-ai/ui-library'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; +import { CanvasEntityGroupTitle } from 'features/controlLayers/components/common/CanvasEntityGroupTitle'; import { RG } from 'features/controlLayers/components/RegionalGuidance/RG'; import { mapId } from 'features/controlLayers/konva/util'; import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; @@ -13,10 +13,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) = export const RGEntityList = memo(() => { const { t } = useTranslation(); - const isTypeSelected = useAppSelector((s) => - Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'regional_guidance') - ); - + const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'regional_guidance')); const rgIds = useAppSelector(selectEntityIds); if (rgIds.length === 0) { @@ -26,13 +23,10 @@ export const RGEntityList = memo(() => { if (rgIds.length > 0) { return ( <> - - {t('controlLayers.regionalGuidance_withCount', { count: rgIds.length })} - + {rgIds.map((id) => ( ))} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGHeader.tsx index ec4cc36b66..866913a08c 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGHeader.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RGHeader.tsx @@ -15,10 +15,11 @@ import { RGSettingsPopover } from './RGSettingsPopover'; type Props = { id: string; + isSelected: boolean; onToggleVisibility: () => void; }; -export const RGHeader = memo(({ id, onToggleVisibility }: Props) => { +export const RGHeader = memo(({ id, isSelected, onToggleVisibility }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const isEnabled = useAppSelector((s) => selectRGOrThrow(s.canvasV2, id).isEnabled); @@ -33,7 +34,7 @@ export const RGHeader = memo(({ id, onToggleVisibility }: Props) => { return ( - + {autoNegative === 'invert' && ( diff --git a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx index 7c0fd05090..9093086fbd 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityContainer.tsx @@ -1,7 +1,7 @@ import type { ChakraProps } from '@invoke-ai/ui-library'; import { Flex } from '@invoke-ai/ui-library'; import type { PropsWithChildren } from 'react'; -import { memo, useCallback, useMemo } from 'react'; +import { memo, useCallback } from 'react'; type Props = PropsWithChildren<{ isSelected: boolean; @@ -9,13 +9,8 @@ type Props = PropsWithChildren<{ selectedBorderColor?: ChakraProps['bg']; }>; -export const CanvasEntityContainer = memo(({ isSelected, onSelect, selectedBorderColor, children }: Props) => { - const borderColor = useMemo(() => { - if (isSelected) { - return selectedBorderColor ?? 'base.400'; - } - return 'base.800'; - }, [isSelected, selectedBorderColor]); +export const CanvasEntityContainer = memo((props: Props) => { + const { isSelected, onSelect, selectedBorderColor = 'base.400', children } = props; const _onSelect = useCallback(() => { if (isSelected) { return; @@ -28,11 +23,10 @@ export const CanvasEntityContainer = memo(({ isSelected, onSelect, selectedBorde position="relative" // necessary for drop overlay flexDir="column" w="full" - bg="base.850" + bg={isSelected ? 'base.800' : 'base.850'} onClick={_onSelect} borderInlineStartWidth={5} - borderColor={borderColor} - opacity={isSelected ? 1 : 0.6} + borderColor={isSelected ? selectedBorderColor : 'base.800'} borderRadius="base" > {children} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityGroupTitle.tsx b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityGroupTitle.tsx new file mode 100644 index 0000000000..69fcefe8c3 --- /dev/null +++ b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityGroupTitle.tsx @@ -0,0 +1,17 @@ +import { Text } from '@invoke-ai/ui-library'; +import { memo } from 'react'; + +type Props = { + title: string; + isSelected: boolean; +}; + +export const CanvasEntityGroupTitle = memo(({ title, isSelected }: Props) => { + return ( + + {title} + + ); +}); + +CanvasEntityGroupTitle.displayName = 'CanvasEntityGroupTitle'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityTitle.tsx b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityTitle.tsx index ce72f2f002..1fc3d6e9f0 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityTitle.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/common/CanvasEntityTitle.tsx @@ -3,11 +3,12 @@ import { memo } from 'react'; type Props = { title: string; + isSelected: boolean; }; -export const CanvasEntityTitle = memo(({ title }: Props) => { +export const CanvasEntityTitle = memo(({ title, isSelected }: Props) => { return ( - + {title} );