feat(ui): simple session initial state cards are buttons

This commit is contained in:
psychedelicious
2025-06-11 12:47:46 +10:00
parent baa9141be3
commit a5e5cbd7c3
7 changed files with 65 additions and 66 deletions

View File

@@ -3,7 +3,6 @@
import { Button, Divider, Flex, Grid, Heading, Text } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { InitialStateAddAStyleReference } from 'features/controlLayers/components/SimpleSession/InitialStateAddAStyleReference';
import { InitialStateCardGridItem } from 'features/controlLayers/components/SimpleSession/InitialStateCardGridItem';
import { InitialStateEditImageCard } from 'features/controlLayers/components/SimpleSession/InitialStateEditImageCard';
import { InitialStateGenerateFromText } from 'features/controlLayers/components/SimpleSession/InitialStateGenerateFromText';
import { InitialStateUseALayoutImageCard } from 'features/controlLayers/components/SimpleSession/InitialStateUseALayoutImageCard';
@@ -29,18 +28,10 @@ export const InitialState = memo(() => {
</Text>
<Grid gridTemplateColumns="1fr 1fr" gridTemplateRows="1fr 1fr" gap={4}>
<InitialStateCardGridItem>
<InitialStateGenerateFromText />
</InitialStateCardGridItem>
<InitialStateCardGridItem>
<InitialStateAddAStyleReference />
</InitialStateCardGridItem>
<InitialStateCardGridItem>
<InitialStateUseALayoutImageCard />
</InitialStateCardGridItem>
<InitialStateCardGridItem>
<InitialStateEditImageCard />
</InitialStateCardGridItem>
<InitialStateGenerateFromText />
<InitialStateAddAStyleReference />
<InitialStateUseALayoutImageCard />
<InitialStateEditImageCard />
</Grid>
<Text fontSize="md" color="base.300" alignSelf="center" mt={6}>

View File

@@ -2,12 +2,13 @@
import { Flex, Heading, Icon, Text } from '@invoke-ai/ui-library';
import { useAppStore } from 'app/store/nanostores/store';
import { UploadImageIconButton } from 'common/hooks/useImageUploadButton';
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
import { InitialStateButtonGridItem } from 'features/controlLayers/components/SimpleSession/InitialStateButtonGridItem';
import { newCanvasFromImageDndTarget } from 'features/dnd/dnd';
import { DndDropTarget } from 'features/dnd/DndDropTarget';
import { newCanvasFromImage } from 'features/imageActions/actions';
import { memo, useCallback } from 'react';
import { PiUserCircleGearBold } from 'react-icons/pi';
import { PiUploadBold, PiUserCircleGearBold } from 'react-icons/pi';
import type { ImageDTO } from 'services/api/types';
const NEW_CANVAS_OPTIONS = { type: 'reference_image' } as const;
@@ -23,17 +24,19 @@ export const InitialStateAddAStyleReference = memo(() => {
},
[dispatch, getState]
);
const uploadApi = useImageUploadButton({ allowMultiple: false, onUpload });
return (
<>
<InitialStateButtonGridItem {...uploadApi.getUploadButtonProps()}>
<Icon as={PiUserCircleGearBold} boxSize={8} color="base.500" />
<Heading size="sm">Add a Style Reference</Heading>
<Text color="base.300">Add an image to transfer its look.</Text>
<Flex w="full" justifyContent="flex-end">
<UploadImageIconButton onUpload={onUpload} variant="link" h={8} />
<Flex w="full" justifyContent="flex-end" p={2}>
<PiUploadBold />
<input {...uploadApi.getUploadInputProps()} />
</Flex>
<DndDropTarget dndTarget={newCanvasFromImageDndTarget} dndTargetData={dndTargetData} label="Drop" />
</>
</InitialStateButtonGridItem>
);
});
InitialStateAddAStyleReference.displayName = 'InitialStateAddAStyleReference';

View File

@@ -0,0 +1,28 @@
import type { GridItemProps } from '@invoke-ai/ui-library';
import { Button, GridItem } from '@invoke-ai/ui-library';
import { memo } from 'react';
export const InitialStateButtonGridItem = memo(({ children, ...rest }: GridItemProps) => {
return (
<GridItem
as={Button}
variant="outline"
display="flex"
position="relative"
flexDir="column"
alignItems="center"
borderWidth={1}
borderRadius="base"
p={2}
pt={6}
gap={2}
w="full"
h="full"
{...rest}
>
{children}
</GridItem>
);
});
InitialStateButtonGridItem.displayName = 'InitialStateButtonGridItem';

View File

@@ -1,24 +0,0 @@
import { GridItem } from '@invoke-ai/ui-library';
import { memo, type PropsWithChildren } from 'react';
export const InitialStateCardGridItem = memo((props: PropsWithChildren) => {
return (
<GridItem
display="flex"
position="relative"
flexDir="column"
alignItems="center"
borderWidth={1}
borderRadius="base"
p={2}
pt={6}
gap={2}
w="full"
h="full"
>
{props.children}
</GridItem>
);
});
InitialStateCardGridItem.displayName = 'InitialStateCardGridItem';

View File

@@ -2,12 +2,13 @@
import { Flex, Heading, Icon, Text } from '@invoke-ai/ui-library';
import { useAppStore } from 'app/store/nanostores/store';
import { UploadImageIconButton } from 'common/hooks/useImageUploadButton';
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
import { InitialStateButtonGridItem } from 'features/controlLayers/components/SimpleSession/InitialStateButtonGridItem';
import { newCanvasFromImageDndTarget } from 'features/dnd/dnd';
import { DndDropTarget } from 'features/dnd/DndDropTarget';
import { newCanvasFromImage } from 'features/imageActions/actions';
import { memo, useCallback } from 'react';
import { PiPencilBold } from 'react-icons/pi';
import { PiPencilBold, PiUploadBold } from 'react-icons/pi';
import type { ImageDTO } from 'services/api/types';
const NEW_CANVAS_OPTIONS = { type: 'raster_layer', withInpaintMask: true } as const;
@@ -23,17 +24,19 @@ export const InitialStateEditImageCard = memo(() => {
},
[dispatch, getState]
);
const uploadApi = useImageUploadButton({ allowMultiple: false, onUpload });
return (
<>
<InitialStateButtonGridItem {...uploadApi.getUploadButtonProps()}>
<Icon as={PiPencilBold} boxSize={8} color="base.500" />
<Heading size="sm">Edit Image</Heading>
<Text color="base.300">Add an image to refine.</Text>
<Flex w="full" justifyContent="flex-end">
<UploadImageIconButton onUpload={onUpload} variant="link" h={8} />
<Flex w="full" justifyContent="flex-end" p={2}>
<PiUploadBold />
<input {...uploadApi.getUploadInputProps()} />
</Flex>
<DndDropTarget dndTarget={newCanvasFromImageDndTarget} dndTargetData={dndTargetData} label="Drop" />
</>
</InitialStateButtonGridItem>
);
});
InitialStateEditImageCard.displayName = 'InitialStateEditImageCard';

View File

@@ -1,6 +1,7 @@
/* eslint-disable i18next/no-literal-string */
import { Flex, Heading, Icon, IconButton, Text } from '@invoke-ai/ui-library';
import { Flex, Heading, Icon, Text } from '@invoke-ai/ui-library';
import { InitialStateButtonGridItem } from 'features/controlLayers/components/SimpleSession/InitialStateButtonGridItem';
import { memo } from 'react';
import { PiCursorTextBold, PiTextAaBold } from 'react-icons/pi';
@@ -14,20 +15,14 @@ const focusOnPrompt = () => {
export const InitialStateGenerateFromText = memo(() => {
return (
<>
<InitialStateButtonGridItem onClick={focusOnPrompt}>
<Icon as={PiTextAaBold} boxSize={8} color="base.500" />
<Heading size="sm">Generate from Text</Heading>
<Text color="base.300">Enter a prompt and Invoke.</Text>
<Flex w="full" justifyContent="flex-end">
<IconButton
onClick={focusOnPrompt}
aria-label="Focus on prompt"
icon={<PiCursorTextBold />}
variant="link"
h={8}
/>
<Flex w="full" justifyContent="flex-end" p={2}>
<PiCursorTextBold />
</Flex>
</>
</InitialStateButtonGridItem>
);
});
InitialStateGenerateFromText.displayName = 'InitialStateGenerateFromText';

View File

@@ -2,12 +2,13 @@
import { Flex, Heading, Icon, Text } from '@invoke-ai/ui-library';
import { useAppStore } from 'app/store/nanostores/store';
import { UploadImageIconButton } from 'common/hooks/useImageUploadButton';
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
import { InitialStateButtonGridItem } from 'features/controlLayers/components/SimpleSession/InitialStateButtonGridItem';
import { newCanvasFromImageDndTarget } from 'features/dnd/dnd';
import { DndDropTarget } from 'features/dnd/DndDropTarget';
import { newCanvasFromImage } from 'features/imageActions/actions';
import { memo, useCallback } from 'react';
import { PiRectangleDashedBold } from 'react-icons/pi';
import { PiRectangleDashedBold, PiUploadBold } from 'react-icons/pi';
import type { ImageDTO } from 'services/api/types';
const NEW_CANVAS_OPTIONS = { type: 'control_layer', withResize: true } as const;
@@ -23,17 +24,19 @@ export const InitialStateUseALayoutImageCard = memo(() => {
},
[dispatch, getState]
);
const uploadApi = useImageUploadButton({ allowMultiple: false, onUpload });
return (
<>
<InitialStateButtonGridItem {...uploadApi.getUploadButtonProps()}>
<Icon as={PiRectangleDashedBold} boxSize={8} color="base.500" />
<Heading size="sm">Use a Layout Image</Heading>
<Text color="base.300">Add an image to control composition.</Text>
<Flex w="full" justifyContent="flex-end">
<UploadImageIconButton onUpload={onUpload} variant="link" h={8} />
<Flex w="full" justifyContent="flex-end" p={2}>
<PiUploadBold />
<input {...uploadApi.getUploadInputProps()} />
</Flex>
<DndDropTarget dndTarget={newCanvasFromImageDndTarget} dndTargetData={dndTargetData} label="Drop" />
</>
</InitialStateButtonGridItem>
);
});
InitialStateUseALayoutImageCard.displayName = 'InitialStateUseALayoutImageCard';