fix(ui): popover ref & wrapping of children (wip)

This commit is contained in:
psychedelicious
2023-09-21 20:01:00 +10:00
committed by Kent Keirsey
parent b6e9cd4fe2
commit 5aefa49d7d
13 changed files with 140 additions and 106 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -72,4 +72,6 @@ const IAISwitch = (props: IAISwitchProps) => {
);
};
IAISwitch.displayName = 'IAISwitch';
export default memo(IAISwitch);