mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): popover ref & wrapping of children (wip)
This commit is contained in:
committed by
Kent Keirsey
parent
b6e9cd4fe2
commit
5aefa49d7d
@ -1,37 +1,43 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
PopoverArrow,
|
||||
PopoverCloseButton,
|
||||
PopoverHeader,
|
||||
PopoverBody,
|
||||
PopoverProps,
|
||||
Divider,
|
||||
Flex,
|
||||
Text,
|
||||
Heading,
|
||||
Image,
|
||||
Popover,
|
||||
PopoverArrow,
|
||||
PopoverBody,
|
||||
PopoverCloseButton,
|
||||
PopoverContent,
|
||||
PopoverProps,
|
||||
PopoverTrigger,
|
||||
Portal,
|
||||
Text,
|
||||
} from '@chakra-ui/react';
|
||||
import { useAppSelector } from '../../app/store/storeHooks';
|
||||
import { ReactNode, memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAppSelector } from '../../app/store/storeHooks';
|
||||
|
||||
interface Props extends PopoverProps {
|
||||
const OPEN_DELAY = 1500;
|
||||
|
||||
type Props = Omit<PopoverProps, 'children'> & {
|
||||
details: string;
|
||||
children: JSX.Element;
|
||||
children: ReactNode;
|
||||
image?: string;
|
||||
buttonLabel?: string;
|
||||
buttonHref?: string;
|
||||
placement?: PopoverProps['placement'];
|
||||
}
|
||||
};
|
||||
|
||||
function IAIInformationalPopover({
|
||||
const IAIInformationalPopover = ({
|
||||
details,
|
||||
image,
|
||||
buttonLabel,
|
||||
buttonHref,
|
||||
children,
|
||||
placement,
|
||||
}: Props): JSX.Element {
|
||||
}: Props) => {
|
||||
const shouldEnableInformationalPopovers = useAppSelector(
|
||||
(state) => state.system.shouldEnableInformationalPopovers
|
||||
);
|
||||
@ -41,18 +47,21 @@ function IAIInformationalPopover({
|
||||
const paragraph = t(`popovers.${details}.paragraph`);
|
||||
|
||||
if (!shouldEnableInformationalPopovers) {
|
||||
return children;
|
||||
} else {
|
||||
return (
|
||||
<Popover
|
||||
placement={placement || 'top'}
|
||||
closeOnBlur={false}
|
||||
trigger="hover"
|
||||
variant="informational"
|
||||
>
|
||||
<PopoverTrigger>
|
||||
<div>{children}</div>
|
||||
</PopoverTrigger>
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover
|
||||
placement={placement || 'top'}
|
||||
closeOnBlur={false}
|
||||
trigger="hover"
|
||||
variant="informational"
|
||||
openDelay={OPEN_DELAY}
|
||||
>
|
||||
<PopoverTrigger>
|
||||
<Box w="full">{children}</Box>
|
||||
</PopoverTrigger>
|
||||
<Portal>
|
||||
<PopoverContent>
|
||||
<PopoverArrow />
|
||||
<PopoverCloseButton />
|
||||
@ -83,14 +92,17 @@ function IAIInformationalPopover({
|
||||
gap: 3,
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
p: 3,
|
||||
pt: heading ? 0 : 3,
|
||||
}}
|
||||
>
|
||||
{heading && <PopoverHeader>{heading}</PopoverHeader>}
|
||||
<Text sx={{ px: 3 }}>{paragraph}</Text>
|
||||
{heading && (
|
||||
<>
|
||||
<Heading size="sm">{heading}</Heading>
|
||||
<Divider />
|
||||
</>
|
||||
)}
|
||||
<Text>{paragraph}</Text>
|
||||
{buttonLabel && (
|
||||
<Flex sx={{ px: 3 }} justifyContent="flex-end">
|
||||
<Flex justifyContent="flex-end">
|
||||
<Button
|
||||
onClick={() => window.open(buttonHref)}
|
||||
size="sm"
|
||||
@ -104,9 +116,9 @@ function IAIInformationalPopover({
|
||||
</Flex>
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
}
|
||||
</Portal>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default IAIInformationalPopover;
|
||||
export default memo(IAIInformationalPopover);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { FormControl, FormLabel, Tooltip } from '@chakra-ui/react';
|
||||
import { FormControl, FormLabel, Tooltip, forwardRef } from '@chakra-ui/react';
|
||||
import { MultiSelect, MultiSelectProps } from '@mantine/core';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
|
||||
@ -11,7 +11,7 @@ type IAIMultiSelectProps = Omit<MultiSelectProps, 'label'> & {
|
||||
label?: string;
|
||||
};
|
||||
|
||||
const IAIMantineMultiSelect = (props: IAIMultiSelectProps) => {
|
||||
const IAIMantineMultiSelect = forwardRef((props: IAIMultiSelectProps, ref) => {
|
||||
const {
|
||||
searchable = true,
|
||||
tooltip,
|
||||
@ -47,7 +47,7 @@ const IAIMantineMultiSelect = (props: IAIMultiSelectProps) => {
|
||||
<MultiSelect
|
||||
label={
|
||||
label ? (
|
||||
<FormControl isDisabled={disabled}>
|
||||
<FormControl ref={ref} isDisabled={disabled}>
|
||||
<FormLabel>{label}</FormLabel>
|
||||
</FormControl>
|
||||
) : undefined
|
||||
@ -63,6 +63,8 @@ const IAIMantineMultiSelect = (props: IAIMultiSelectProps) => {
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
IAIMantineMultiSelect.displayName = 'IAIMantineMultiSelect';
|
||||
|
||||
export default memo(IAIMantineMultiSelect);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { FormControl, FormLabel, Tooltip } from '@chakra-ui/react';
|
||||
import { FormControl, FormLabel, Tooltip, forwardRef } from '@chakra-ui/react';
|
||||
import { Select, SelectProps } from '@mantine/core';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
|
||||
@ -17,7 +17,7 @@ type IAISelectProps = Omit<SelectProps, 'label'> & {
|
||||
inputRef?: RefObject<HTMLInputElement>;
|
||||
};
|
||||
|
||||
const IAIMantineSearchableSelect = (props: IAISelectProps) => {
|
||||
const IAIMantineSearchableSelect = forwardRef((props: IAISelectProps, ref) => {
|
||||
const {
|
||||
searchable = true,
|
||||
tooltip,
|
||||
@ -74,7 +74,7 @@ const IAIMantineSearchableSelect = (props: IAISelectProps) => {
|
||||
ref={inputRef}
|
||||
label={
|
||||
label ? (
|
||||
<FormControl isDisabled={disabled}>
|
||||
<FormControl ref={ref} isDisabled={disabled}>
|
||||
<FormLabel>{label}</FormLabel>
|
||||
</FormControl>
|
||||
) : undefined
|
||||
@ -92,6 +92,8 @@ const IAIMantineSearchableSelect = (props: IAISelectProps) => {
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
IAIMantineSearchableSelect.displayName = 'IAIMantineSearchableSelect';
|
||||
|
||||
export default memo(IAIMantineSearchableSelect);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { FormControl, FormLabel, Tooltip } from '@chakra-ui/react';
|
||||
import { FormControl, FormLabel, Tooltip, forwardRef } from '@chakra-ui/react';
|
||||
import { Select, SelectProps } from '@mantine/core';
|
||||
import { useMantineSelectStyles } from 'mantine-theme/hooks/useMantineSelectStyles';
|
||||
import { RefObject, memo } from 'react';
|
||||
@ -15,7 +15,7 @@ export type IAISelectProps = Omit<SelectProps, 'label'> & {
|
||||
label?: string;
|
||||
};
|
||||
|
||||
const IAIMantineSelect = (props: IAISelectProps) => {
|
||||
const IAIMantineSelect = forwardRef((props: IAISelectProps, ref) => {
|
||||
const { tooltip, inputRef, label, disabled, required, ...rest } = props;
|
||||
|
||||
const styles = useMantineSelectStyles();
|
||||
@ -25,7 +25,7 @@ const IAIMantineSelect = (props: IAISelectProps) => {
|
||||
<Select
|
||||
label={
|
||||
label ? (
|
||||
<FormControl isRequired={required} isDisabled={disabled}>
|
||||
<FormControl ref={ref} isRequired={required} isDisabled={disabled}>
|
||||
<FormLabel>{label}</FormLabel>
|
||||
</FormControl>
|
||||
) : undefined
|
||||
@ -37,6 +37,8 @@ const IAIMantineSelect = (props: IAISelectProps) => {
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
IAIMantineSelect.displayName = 'IAIMantineSelect';
|
||||
|
||||
export default memo(IAIMantineSelect);
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
NumberInputStepperProps,
|
||||
Tooltip,
|
||||
TooltipProps,
|
||||
forwardRef,
|
||||
} from '@chakra-ui/react';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
||||
@ -50,7 +51,7 @@ interface Props extends Omit<NumberInputProps, 'onChange'> {
|
||||
/**
|
||||
* Customized Chakra FormControl + NumberInput multi-part component.
|
||||
*/
|
||||
const IAINumberInput = (props: Props) => {
|
||||
const IAINumberInput = forwardRef((props: Props, ref) => {
|
||||
const {
|
||||
label,
|
||||
isDisabled = false,
|
||||
@ -141,6 +142,7 @@ const IAINumberInput = (props: Props) => {
|
||||
return (
|
||||
<Tooltip {...tooltipProps}>
|
||||
<FormControl
|
||||
ref={ref}
|
||||
isDisabled={isDisabled}
|
||||
isInvalid={isInvalid}
|
||||
{...formControlProps}
|
||||
@ -172,6 +174,8 @@ const IAINumberInput = (props: Props) => {
|
||||
</FormControl>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
IAINumberInput.displayName = 'IAINumberInput';
|
||||
|
||||
export default memo(IAINumberInput);
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
SliderTrackProps,
|
||||
Tooltip,
|
||||
TooltipProps,
|
||||
forwardRef,
|
||||
} from '@chakra-ui/react';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { roundDownToMultiple } from 'common/util/roundDownToMultiple';
|
||||
@ -71,7 +72,7 @@ export type IAIFullSliderProps = {
|
||||
sliderIAIIconButtonProps?: IAIIconButtonProps;
|
||||
};
|
||||
|
||||
const IAISlider = (props: IAIFullSliderProps) => {
|
||||
const IAISlider = forwardRef((props: IAIFullSliderProps, ref) => {
|
||||
const [showTooltip, setShowTooltip] = useState(false);
|
||||
const {
|
||||
label,
|
||||
@ -187,6 +188,7 @@ const IAISlider = (props: IAIFullSliderProps) => {
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
ref={ref}
|
||||
onClick={forceInputBlur}
|
||||
sx={
|
||||
isCompact
|
||||
@ -354,6 +356,8 @@ const IAISlider = (props: IAIFullSliderProps) => {
|
||||
</HStack>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
IAISlider.displayName = 'IAISlider';
|
||||
|
||||
export default memo(IAISlider);
|
||||
|
@ -72,4 +72,6 @@ const IAISwitch = (props: IAISwitchProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
IAISwitch.displayName = 'IAISwitch';
|
||||
|
||||
export default memo(IAISwitch);
|
||||
|
Reference in New Issue
Block a user