add informational popover base component and sample

This commit is contained in:
Mary Hipp 2023-09-12 16:10:43 -04:00
parent e467ca7f1b
commit 63f94579c5
5 changed files with 166 additions and 12 deletions

View File

@ -0,0 +1,98 @@
import {
Button,
Popover,
PopoverTrigger,
PopoverContent,
PopoverArrow,
PopoverCloseButton,
PopoverHeader,
PopoverBody,
PopoverProps,
Flex,
Text,
Image,
} from '@chakra-ui/react';
import { ReactNode } from 'react';
interface Props extends PopoverProps {
heading: string;
paragraph: string;
triggerComponent: ReactNode;
image?: string;
buttonLabel?: string;
buttonHref?: string;
}
function IAIInformationalPopover({
heading,
paragraph,
image,
buttonLabel,
buttonHref,
triggerComponent,
}: Props) {
return (
<Popover
placement="top"
closeOnBlur={false}
trigger="hover"
variant="informational"
>
<PopoverTrigger>
<div>{triggerComponent}</div>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverCloseButton />
<PopoverBody>
<Flex
sx={{
gap: 3,
flexDirection: 'column',
width: '100%',
}}
>
{image && (
<Image
sx={{
objectFit: 'contain',
maxW: '100%',
maxH: 'full',
backgroundColor: 'white',
}}
src={image}
alt="Optional Image"
/>
)}
<Flex
sx={{
gap: 3,
flexDirection: 'column',
p: 3,
pt: 0,
}}
>
<PopoverHeader>{heading}</PopoverHeader>
<Text sx={{ pl: 3, pr: 3 }}>{paragraph}</Text>
{buttonLabel && (
<Flex sx={{ pl: 3, pr: 3 }} justifyContent="flex-end">
<Button
onClick={() => window.open(buttonHref)}
size="sm"
variant="invokeAIOutline"
>
{buttonLabel}
</Button>
</Flex>
)}
</Flex>
</Flex>
</PopoverBody>
</PopoverContent>
</Popover>
);
}
export default IAIInformationalPopover;

View File

@ -0,0 +1,16 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import InvokeAILogoImage from 'assets/images/logo.png';
export const ParamPositiveConditioningPopover = (props: PropsWithChildren) => {
return (
<IAIInformationalPopover
heading="Prompt Box"
paragraph="This is where you enter your prompt"
buttonLabel="Learn more"
buttonHref="http://google.com"
image={InvokeAILogoImage}
triggerComponent={props.children}
/>
);
};

View File

@ -1,4 +1,11 @@
import { Box, FormControl, useDisclosure } from '@chakra-ui/react';
import {
Box,
FormControl,
Text,
Tooltip,
useDisclosure,
Heading,
} from '@chakra-ui/react';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
@ -20,6 +27,9 @@ import { flushSync } from 'react-dom';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
import IAIInformationalPopover from '../../../../../common/components/IAIInformationalPopover';
import InvokeAILogoImage from 'assets/images/logo.png';
import { ParamPositiveConditioningPopover } from '../../../../informationalPopovers/components/paramPositiveConditioning';
const promptInputSelector = createSelector(
[stateSelector, activeTabNameSelector],
@ -129,17 +139,19 @@ const ParamPositiveConditioning = () => {
onClose={onClose}
onSelect={handleSelectEmbedding}
>
<IAITextarea
id="prompt"
name="prompt"
ref={promptRef}
value={prompt}
placeholder={t('parameters.positivePromptPlaceholder')}
onChange={handleChangePrompt}
onKeyDown={handleKeyDown}
resize="vertical"
minH={32}
/>
<ParamPositiveConditioningPopover>
<IAITextarea
id="prompt"
name="prompt"
ref={promptRef}
value={prompt}
placeholder={t('parameters.positivePromptPlaceholder')}
onChange={handleChangePrompt}
onKeyDown={handleKeyDown}
resize="vertical"
minH={32}
/>
</ParamPositiveConditioningPopover>
</ParamEmbeddingPopover>
</FormControl>
{!isOpen && isEmbeddingEnabled && (

View File

@ -92,6 +92,13 @@ const invokeAIOutline = defineStyle((props) => {
return {
border: '1px solid',
borderColor: c === 'gray' ? borderColor : 'currentColor',
_hover: {
bg: mode(`${c}.500`, `${c}.500`)(props),
color: mode('white', `base.50`)(props),
svg: {
fill: mode('white', `base.50`)(props),
},
},
'.chakra-button__group[data-attached][data-orientation=horizontal] > &:not(:last-of-type)':
{
marginEnd: '-1px',

View File

@ -29,13 +29,34 @@ const invokeAIContent = defineStyle((props) => {
};
});
const informationalContent = defineStyle((props) => {
return {
[$arrowBg.variable]: mode('colors.base.100', 'colors.base.600')(props),
[$popperBg.variable]: mode('colors.base.100', 'colors.base.600')(props),
[$arrowShadowColor.variable]: mode(
'colors.base.400',
'colors.base.400'
)(props),
p: 0,
bg: mode('base.100', 'base.600')(props),
border: 'none',
shadow: 'dark-lg',
};
});
const invokeAI = definePartsStyle((props) => ({
content: invokeAIContent(props),
}));
const informational = definePartsStyle((props) => ({
content: informationalContent(props),
body: { padding: 0 },
}));
export const popoverTheme = defineMultiStyleConfig({
variants: {
invokeAI,
informational,
},
defaultProps: {
variant: 'invokeAI',