mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): memoize all components
This commit is contained in:
parent
ca4b8e65c1
commit
56527da73e
@ -1,4 +1,4 @@
|
|||||||
import { PropsWithChildren, useEffect } from 'react';
|
import { PropsWithChildren, memo, useEffect } from 'react';
|
||||||
import { modelChanged } from '../src/features/parameters/store/generationSlice';
|
import { modelChanged } from '../src/features/parameters/store/generationSlice';
|
||||||
import { useAppDispatch } from '../src/app/store/storeHooks';
|
import { useAppDispatch } from '../src/app/store/storeHooks';
|
||||||
import { useGlobalModifiersInit } from '../src/common/hooks/useGlobalModifiers';
|
import { useGlobalModifiersInit } from '../src/common/hooks/useGlobalModifiers';
|
||||||
@ -6,7 +6,7 @@ import { useGlobalModifiersInit } from '../src/common/hooks/useGlobalModifiers';
|
|||||||
* Initializes some state for storybook. Must be in a different component
|
* Initializes some state for storybook. Must be in a different component
|
||||||
* so that it is run inside the redux context.
|
* so that it is run inside the redux context.
|
||||||
*/
|
*/
|
||||||
export const ReduxInit = (props: PropsWithChildren) => {
|
export const ReduxInit = memo((props: PropsWithChildren) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
useGlobalModifiersInit();
|
useGlobalModifiersInit();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -20,4 +20,6 @@ export const ReduxInit = (props: PropsWithChildren) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return props.children;
|
return props.children;
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ReduxInit.displayName = 'ReduxInit';
|
||||||
|
@ -22,7 +22,7 @@ const exit: AnimationProps['exit'] = {
|
|||||||
transition: { duration: 0.1 },
|
transition: { duration: 0.1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IAIDropOverlay = (props: Props) => {
|
const IAIDropOverlay = (props: Props) => {
|
||||||
const { isOver, label = 'Drop' } = props;
|
const { isOver, label = 'Drop' } = props;
|
||||||
const motionId = useRef(uuidv4());
|
const motionId = useRef(uuidv4());
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { As, FlexProps, StyleProps } from '@chakra-ui/react';
|
import type { As, FlexProps, StyleProps } from '@chakra-ui/react';
|
||||||
import { Flex, Icon, Skeleton, Spinner } from '@chakra-ui/react';
|
import { Flex, Icon, Skeleton, Spinner } from '@chakra-ui/react';
|
||||||
import { useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { FaImage } from 'react-icons/fa';
|
import { FaImage } from 'react-icons/fa';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
import type { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ import { InvText } from './InvText/wrapper';
|
|||||||
|
|
||||||
type Props = { image: ImageDTO | undefined };
|
type Props = { image: ImageDTO | undefined };
|
||||||
|
|
||||||
export const IAILoadingImageFallback = (props: Props) => {
|
export const IAILoadingImageFallback = memo((props: Props) => {
|
||||||
if (props.image) {
|
if (props.image) {
|
||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
@ -33,7 +33,8 @@ export const IAILoadingImageFallback = (props: Props) => {
|
|||||||
<Spinner size="xl" />
|
<Spinner size="xl" />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
IAILoadingImageFallback.displayName = 'IAILoadingImageFallback';
|
||||||
|
|
||||||
type IAINoImageFallbackProps = FlexProps & {
|
type IAINoImageFallbackProps = FlexProps & {
|
||||||
label?: string;
|
label?: string;
|
||||||
@ -41,7 +42,7 @@ type IAINoImageFallbackProps = FlexProps & {
|
|||||||
boxSize?: StyleProps['boxSize'];
|
boxSize?: StyleProps['boxSize'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IAINoContentFallback = (props: IAINoImageFallbackProps) => {
|
export const IAINoContentFallback = memo((props: IAINoImageFallbackProps) => {
|
||||||
const { icon = FaImage, boxSize = 16, sx, ...rest } = props;
|
const { icon = FaImage, boxSize = 16, sx, ...rest } = props;
|
||||||
|
|
||||||
const styles = useMemo(
|
const styles = useMemo(
|
||||||
@ -67,15 +68,15 @@ export const IAINoContentFallback = (props: IAINoImageFallbackProps) => {
|
|||||||
{props.label && <InvText textAlign="center">{props.label}</InvText>}
|
{props.label && <InvText textAlign="center">{props.label}</InvText>}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
IAINoContentFallback.displayName = 'IAINoContentFallback';
|
||||||
|
|
||||||
type IAINoImageFallbackWithSpinnerProps = FlexProps & {
|
type IAINoImageFallbackWithSpinnerProps = FlexProps & {
|
||||||
label?: string;
|
label?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IAINoContentFallbackWithSpinner = (
|
export const IAINoContentFallbackWithSpinner = memo(
|
||||||
props: IAINoImageFallbackWithSpinnerProps
|
(props: IAINoImageFallbackWithSpinnerProps) => {
|
||||||
) => {
|
|
||||||
const { sx, ...rest } = props;
|
const { sx, ...rest } = props;
|
||||||
const styles = useMemo(
|
const styles = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@ -100,4 +101,6 @@ export const IAINoContentFallbackWithSpinner = (
|
|||||||
{props.label && <InvText textAlign="center">{props.label}</InvText>}
|
{props.label && <InvText textAlign="center">{props.label}</InvText>}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
IAINoContentFallbackWithSpinner.displayName = 'IAINoContentFallbackWithSpinner';
|
||||||
|
@ -2,15 +2,14 @@ import { Box, forwardRef, Textarea as ChakraTextarea } from '@chakra-ui/react';
|
|||||||
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
||||||
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
||||||
import type { KeyboardEvent } from 'react';
|
import type { KeyboardEvent } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import ResizeTextarea from 'react-textarea-autosize';
|
import ResizeTextarea from 'react-textarea-autosize';
|
||||||
|
|
||||||
import type { InvAutosizeTextareaProps } from './types';
|
import type { InvAutosizeTextareaProps } from './types';
|
||||||
|
|
||||||
export const InvAutosizeTextarea = forwardRef<
|
export const InvAutosizeTextarea = memo(
|
||||||
InvAutosizeTextareaProps,
|
forwardRef<InvAutosizeTextareaProps, typeof ResizeTextarea>(
|
||||||
typeof ResizeTextarea
|
(props: InvAutosizeTextareaProps, ref) => {
|
||||||
>((props: InvAutosizeTextareaProps, ref) => {
|
|
||||||
const { setShift } = useGlobalModifiersSetters();
|
const { setShift } = useGlobalModifiersSetters();
|
||||||
const onKeyUpDown = useCallback(
|
const onKeyUpDown = useCallback(
|
||||||
(e: KeyboardEvent<HTMLTextAreaElement>) => {
|
(e: KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
@ -34,4 +33,8 @@ export const InvAutosizeTextarea = forwardRef<
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
InvAutosizeTextarea.displayName = 'InvAutosizeTextarea';
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import { Button, forwardRef } from '@chakra-ui/react';
|
import { Button, forwardRef } from '@chakra-ui/react';
|
||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import type { InvButtonProps } from './types';
|
import type { InvButtonProps } from './types';
|
||||||
|
|
||||||
export const InvButton = forwardRef<InvButtonProps, typeof Button>(
|
export const InvButton = memo(
|
||||||
|
forwardRef<InvButtonProps, typeof Button>(
|
||||||
({ isChecked, tooltip, children, ...rest }: InvButtonProps, ref) => {
|
({ isChecked, tooltip, children, ...rest }: InvButtonProps, ref) => {
|
||||||
if (tooltip) {
|
if (tooltip) {
|
||||||
return (
|
return (
|
||||||
<InvTooltip label={tooltip}>
|
<InvTooltip label={tooltip}>
|
||||||
<Button ref={ref} colorScheme={isChecked ? 'blue' : 'base'} {...rest}>
|
<Button
|
||||||
|
ref={ref}
|
||||||
|
colorScheme={isChecked ? 'blue' : 'base'}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Button>
|
</Button>
|
||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
@ -21,4 +27,7 @@ export const InvButton = forwardRef<InvButtonProps, typeof Button>(
|
|||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvButton.displayName = 'InvButton';
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import { ButtonGroup, forwardRef } from '@chakra-ui/react';
|
import { ButtonGroup, forwardRef } from '@chakra-ui/react';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import type { InvButtonGroupProps } from './types';
|
import type { InvButtonGroupProps } from './types';
|
||||||
|
|
||||||
export const InvButtonGroup = forwardRef<
|
export const InvButtonGroup = memo(
|
||||||
InvButtonGroupProps,
|
forwardRef<InvButtonGroupProps, typeof ButtonGroup>(
|
||||||
typeof ButtonGroup
|
({ isAttached = true, ...rest }: InvButtonGroupProps, ref) => {
|
||||||
>(({ isAttached = true, ...rest }: InvButtonGroupProps, ref) => {
|
|
||||||
return <ButtonGroup ref={ref} isAttached={isAttached} {...rest} />;
|
return <ButtonGroup ref={ref} isAttached={isAttached} {...rest} />;
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
InvButtonGroup.displayName = 'InvButtonGroup';
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
InvAlertDialogOverlay,
|
InvAlertDialogOverlay,
|
||||||
} from 'common/components/InvAlertDialog/wrapper';
|
} from 'common/components/InvAlertDialog/wrapper';
|
||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import { useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import type { InvConfirmationAlertDialogProps } from './types';
|
import type { InvConfirmationAlertDialogProps } from './types';
|
||||||
@ -16,9 +16,8 @@ import type { InvConfirmationAlertDialogProps } from './types';
|
|||||||
* This component is a wrapper around InvAlertDialog that provides a confirmation dialog.
|
* This component is a wrapper around InvAlertDialog that provides a confirmation dialog.
|
||||||
* Its state must be managed externally using chakra's `useDisclosure()` hook.
|
* Its state must be managed externally using chakra's `useDisclosure()` hook.
|
||||||
*/
|
*/
|
||||||
export const InvConfirmationAlertDialog = (
|
export const InvConfirmationAlertDialog = memo(
|
||||||
props: InvConfirmationAlertDialogProps
|
(props: InvConfirmationAlertDialogProps) => {
|
||||||
) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -71,4 +70,7 @@ export const InvConfirmationAlertDialog = (
|
|||||||
</InvAlertDialogOverlay>
|
</InvAlertDialogOverlay>
|
||||||
</InvAlertDialog>
|
</InvAlertDialog>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
InvConfirmationAlertDialog.displayName = 'InvConfirmationAlertDialog';
|
||||||
|
@ -16,7 +16,7 @@ import type { MenuButtonProps, MenuProps, PortalProps } from '@chakra-ui/react';
|
|||||||
import { Portal, useEventListener } from '@chakra-ui/react';
|
import { Portal, useEventListener } from '@chakra-ui/react';
|
||||||
import { InvMenu, InvMenuButton } from 'common/components/InvMenu/wrapper';
|
import { InvMenu, InvMenuButton } from 'common/components/InvMenu/wrapper';
|
||||||
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
|
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
export interface InvContextMenuProps<T extends HTMLElement = HTMLDivElement> {
|
export interface InvContextMenuProps<T extends HTMLElement = HTMLDivElement> {
|
||||||
renderMenu: () => JSX.Element | null;
|
renderMenu: () => JSX.Element | null;
|
||||||
@ -26,9 +26,8 @@ export interface InvContextMenuProps<T extends HTMLElement = HTMLDivElement> {
|
|||||||
menuButtonProps?: MenuButtonProps;
|
menuButtonProps?: MenuButtonProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InvContextMenu = <T extends HTMLElement = HTMLElement>(
|
export const InvContextMenu = memo(
|
||||||
props: InvContextMenuProps<T>
|
<T extends HTMLElement = HTMLElement>(props: InvContextMenuProps<T>) => {
|
||||||
) => {
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isRendered, setIsRendered] = useState(false);
|
const [isRendered, setIsRendered] = useState(false);
|
||||||
const [isDeferredOpen, setIsDeferredOpen] = useState(false);
|
const [isDeferredOpen, setIsDeferredOpen] = useState(false);
|
||||||
@ -111,4 +110,7 @@ export const InvContextMenu = <T extends HTMLElement = HTMLElement>(
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
InvContextMenu.displayName = 'InvContextMenu';
|
||||||
|
@ -5,12 +5,13 @@ import {
|
|||||||
forwardRef,
|
forwardRef,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { InvControlGroupContext } from 'common/components/InvControl/InvControlGroup';
|
import { InvControlGroupContext } from 'common/components/InvControl/InvControlGroup';
|
||||||
import { useContext } from 'react';
|
import { memo, useContext } from 'react';
|
||||||
|
|
||||||
import { InvLabel } from './InvLabel';
|
import { InvLabel } from './InvLabel';
|
||||||
import type { InvControlProps } from './types';
|
import type { InvControlProps } from './types';
|
||||||
|
|
||||||
export const InvControl = forwardRef<InvControlProps, typeof ChakraFormControl>(
|
export const InvControl = memo(
|
||||||
|
forwardRef<InvControlProps, typeof ChakraFormControl>(
|
||||||
(props: InvControlProps, ref) => {
|
(props: InvControlProps, ref) => {
|
||||||
const {
|
const {
|
||||||
children,
|
children,
|
||||||
@ -72,4 +73,7 @@ export const InvControl = forwardRef<InvControlProps, typeof ChakraFormControl>(
|
|||||||
</ChakraFormControl>
|
</ChakraFormControl>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvControl.displayName = 'InvControl';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { FormLabelProps } from '@chakra-ui/react';
|
import type { FormLabelProps } from '@chakra-ui/react';
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { createContext } from 'react';
|
import { createContext, memo } from 'react';
|
||||||
|
|
||||||
export type InvControlGroupProps = {
|
export type InvControlGroupProps = {
|
||||||
labelProps?: FormLabelProps;
|
labelProps?: FormLabelProps;
|
||||||
@ -10,13 +10,14 @@ export type InvControlGroupProps = {
|
|||||||
|
|
||||||
export const InvControlGroupContext = createContext<InvControlGroupProps>({});
|
export const InvControlGroupContext = createContext<InvControlGroupProps>({});
|
||||||
|
|
||||||
export const InvControlGroup = ({
|
export const InvControlGroup = memo(
|
||||||
children,
|
({ children, ...context }: PropsWithChildren<InvControlGroupProps>) => {
|
||||||
...context
|
|
||||||
}: PropsWithChildren<InvControlGroupProps>) => {
|
|
||||||
return (
|
return (
|
||||||
<InvControlGroupContext.Provider value={context}>
|
<InvControlGroupContext.Provider value={context}>
|
||||||
{children}
|
{children}
|
||||||
</InvControlGroupContext.Provider>
|
</InvControlGroupContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
InvControlGroup.displayName = 'InvControlGroup';
|
||||||
|
@ -4,7 +4,7 @@ import { stateSelector } from 'app/store/store';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
|
||||||
import { InvControlGroupContext } from 'common/components/InvControl/InvControlGroup';
|
import { InvControlGroupContext } from 'common/components/InvControl/InvControlGroup';
|
||||||
import { useContext } from 'react';
|
import { memo, useContext } from 'react';
|
||||||
|
|
||||||
import type { InvLabelProps } from './types';
|
import type { InvLabelProps } from './types';
|
||||||
|
|
||||||
@ -13,7 +13,8 @@ const selector = createSelector(
|
|||||||
({ system }) => system.shouldEnableInformationalPopovers
|
({ system }) => system.shouldEnableInformationalPopovers
|
||||||
);
|
);
|
||||||
|
|
||||||
export const InvLabel = forwardRef<InvLabelProps, typeof FormLabel>(
|
export const InvLabel = memo(
|
||||||
|
forwardRef<InvLabelProps, typeof FormLabel>(
|
||||||
(
|
(
|
||||||
{ feature, renderInfoPopoverInPortal, children, ...rest }: InvLabelProps,
|
{ feature, renderInfoPopoverInPortal, children, ...rest }: InvLabelProps,
|
||||||
ref
|
ref
|
||||||
@ -40,4 +41,7 @@ export const InvLabel = forwardRef<InvLabelProps, typeof FormLabel>(
|
|||||||
</FormLabel>
|
</FormLabel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvLabel.displayName = 'InvLabel';
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { forwardRef, IconButton } from '@chakra-ui/react';
|
import { forwardRef, IconButton } from '@chakra-ui/react';
|
||||||
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const InvIconButton = forwardRef<InvIconButtonProps, typeof IconButton>(
|
export const InvIconButton = memo(
|
||||||
|
forwardRef<InvIconButtonProps, typeof IconButton>(
|
||||||
({ isChecked, tooltip, ...rest }: InvIconButtonProps, ref) => {
|
({ isChecked, tooltip, ...rest }: InvIconButtonProps, ref) => {
|
||||||
if (tooltip) {
|
if (tooltip) {
|
||||||
return (
|
return (
|
||||||
@ -24,4 +26,7 @@ export const InvIconButton = forwardRef<InvIconButtonProps, typeof IconButton>(
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvIconButton.displayName = 'InvIconButton';
|
||||||
|
@ -2,12 +2,12 @@ import { forwardRef, Input } from '@chakra-ui/react';
|
|||||||
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
||||||
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
||||||
import type { KeyboardEvent } from 'react';
|
import type { KeyboardEvent } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
import type { InvInputProps } from './types';
|
import type { InvInputProps } from './types';
|
||||||
|
|
||||||
export const InvInput = forwardRef<InvInputProps, typeof Input>(
|
export const InvInput = memo(
|
||||||
(props: InvInputProps, ref) => {
|
forwardRef<InvInputProps, typeof Input>((props: InvInputProps, ref) => {
|
||||||
const { setShift } = useGlobalModifiersSetters();
|
const { setShift } = useGlobalModifiersSetters();
|
||||||
const onKeyUpDown = useCallback(
|
const onKeyUpDown = useCallback(
|
||||||
(e: KeyboardEvent<HTMLInputElement>) => {
|
(e: KeyboardEvent<HTMLInputElement>) => {
|
||||||
@ -24,5 +24,7 @@ export const InvInput = forwardRef<InvInputProps, typeof Input>(
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvInput.displayName = 'InvInput';
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
keyframes,
|
keyframes,
|
||||||
MenuItem as ChakraMenuItem,
|
MenuItem as ChakraMenuItem,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
import {memo} from'react'
|
||||||
|
|
||||||
import type { InvMenuItemProps } from './types';
|
import type { InvMenuItemProps } from './types';
|
||||||
|
|
||||||
@ -16,7 +17,8 @@ const spin = keyframes`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const InvMenuItem = forwardRef<InvMenuItemProps, typeof ChakraMenuItem>(
|
export const InvMenuItem = memo(
|
||||||
|
forwardRef<InvMenuItemProps, typeof ChakraMenuItem>(
|
||||||
(props: InvMenuItemProps, ref) => {
|
(props: InvMenuItemProps, ref) => {
|
||||||
const {
|
const {
|
||||||
isDestructive = false,
|
isDestructive = false,
|
||||||
@ -41,4 +43,7 @@ export const InvMenuItem = forwardRef<InvMenuItemProps, typeof ChakraMenuItem>(
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvMenuItem.displayName = 'InvMenuItem';
|
||||||
|
@ -3,11 +3,13 @@ import {
|
|||||||
MenuList as ChakraMenuList,
|
MenuList as ChakraMenuList,
|
||||||
Portal,
|
Portal,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import { menuListMotionProps } from './constants';
|
import { menuListMotionProps } from './constants';
|
||||||
import type { InvMenuListProps } from './types';
|
import type { InvMenuListProps } from './types';
|
||||||
|
|
||||||
export const InvMenuList = forwardRef<InvMenuListProps, typeof ChakraMenuList>(
|
export const InvMenuList = memo(
|
||||||
|
forwardRef<InvMenuListProps, typeof ChakraMenuList>(
|
||||||
(props: InvMenuListProps, ref) => {
|
(props: InvMenuListProps, ref) => {
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
@ -19,4 +21,7 @@ export const InvMenuList = forwardRef<InvMenuListProps, typeof ChakraMenuList>(
|
|||||||
</Portal>
|
</Portal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvMenuList.displayName = 'InvMenuList';
|
||||||
|
@ -5,7 +5,7 @@ import { roundToMultiple } from 'common/util/roundDownToMultiple';
|
|||||||
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
||||||
import { clamp } from 'lodash-es';
|
import { clamp } from 'lodash-es';
|
||||||
import type { FocusEventHandler } from 'react';
|
import type { FocusEventHandler } from 'react';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { InvNumberInputField } from './InvNumberInputField';
|
import { InvNumberInputField } from './InvNumberInputField';
|
||||||
import { InvNumberInputStepper } from './InvNumberInputStepper';
|
import { InvNumberInputStepper } from './InvNumberInputStepper';
|
||||||
@ -13,10 +13,9 @@ import type { InvNumberInputProps } from './types';
|
|||||||
|
|
||||||
const isValidCharacter = (char: string) => /^[0-9\-.]$/i.test(char);
|
const isValidCharacter = (char: string) => /^[0-9\-.]$/i.test(char);
|
||||||
|
|
||||||
export const InvNumberInput = forwardRef<
|
export const InvNumberInput = memo(
|
||||||
InvNumberInputProps,
|
forwardRef<InvNumberInputProps, typeof ChakraNumberInput>(
|
||||||
typeof ChakraNumberInput
|
(props: InvNumberInputProps, ref) => {
|
||||||
>((props: InvNumberInputProps, ref) => {
|
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
min = 0,
|
min = 0,
|
||||||
@ -82,7 +81,16 @@ export const InvNumberInput = forwardRef<
|
|||||||
onChange(String(clampedValue), clampedValue);
|
onChange(String(clampedValue), clampedValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_fineStep, _step, isInteger, max, min, onChange, precision, valueAsNumber]
|
[
|
||||||
|
_fineStep,
|
||||||
|
_step,
|
||||||
|
isInteger,
|
||||||
|
max,
|
||||||
|
min,
|
||||||
|
onChange,
|
||||||
|
precision,
|
||||||
|
valueAsNumber,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,4 +126,8 @@ export const InvNumberInput = forwardRef<
|
|||||||
<InvNumberInputStepper />
|
<InvNumberInputStepper />
|
||||||
</ChakraNumberInput>
|
</ChakraNumberInput>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
InvNumberInput.displayName = 'InvNumberInput';
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { NumberInputField as ChakraNumberInputField } from '@chakra-ui/react';
|
import { NumberInputField as ChakraNumberInputField } from '@chakra-ui/react';
|
||||||
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
||||||
import type { KeyboardEventHandler } from 'react';
|
import type { KeyboardEventHandler } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
import type { InvNumberInputFieldProps } from './types';
|
import type { InvNumberInputFieldProps } from './types';
|
||||||
|
|
||||||
export const InvNumberInputField = (props: InvNumberInputFieldProps) => {
|
export const InvNumberInputField = memo((props: InvNumberInputFieldProps) => {
|
||||||
const { onKeyUp, onKeyDown, children, ...rest } = props;
|
const { onKeyUp, onKeyDown, children, ...rest } = props;
|
||||||
const { setShift } = useGlobalModifiersSetters();
|
const { setShift } = useGlobalModifiersSetters();
|
||||||
|
|
||||||
@ -29,4 +29,6 @@ export const InvNumberInputField = (props: InvNumberInputFieldProps) => {
|
|||||||
{children}
|
{children}
|
||||||
</ChakraNumberInputField>
|
</ChakraNumberInputField>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
InvNumberInputField.displayName = 'InvNumberInputField';
|
||||||
|
@ -5,14 +5,14 @@ import {
|
|||||||
NumberIncrementStepper as ChakraNumberIncrementStepper,
|
NumberIncrementStepper as ChakraNumberIncrementStepper,
|
||||||
NumberInputStepper as ChakraNumberInputStepper,
|
NumberInputStepper as ChakraNumberInputStepper,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
import { memo } from 'react';
|
||||||
import { FaMinus, FaPlus } from 'react-icons/fa6';
|
import { FaMinus, FaPlus } from 'react-icons/fa6';
|
||||||
|
|
||||||
import type { InvNumberInputStepperProps } from './types';
|
import type { InvNumberInputStepperProps } from './types';
|
||||||
|
|
||||||
export const InvNumberInputStepper = forwardRef<
|
export const InvNumberInputStepper = memo(
|
||||||
InvNumberInputStepperProps,
|
forwardRef<InvNumberInputStepperProps, typeof ChakraNumberInputStepper>(
|
||||||
typeof ChakraNumberInputStepper
|
(props: InvNumberInputStepperProps, ref) => {
|
||||||
>((props: InvNumberInputStepperProps, ref) => {
|
|
||||||
return (
|
return (
|
||||||
<ChakraNumberInputStepper ref={ref} {...props}>
|
<ChakraNumberInputStepper ref={ref} {...props}>
|
||||||
<ChakraNumberIncrementStepper>
|
<ChakraNumberIncrementStepper>
|
||||||
@ -23,4 +23,8 @@ export const InvNumberInputStepper = forwardRef<
|
|||||||
</ChakraNumberDecrementStepper>
|
</ChakraNumberDecrementStepper>
|
||||||
</ChakraNumberInputStepper>
|
</ChakraNumberInputStepper>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
InvNumberInputStepper.displayName = 'InvNumberInputStepper';
|
||||||
|
@ -10,12 +10,14 @@ import type { InvFormattedMark } from 'common/components/InvSlider/types';
|
|||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
import { $modifiers } from 'common/hooks/useGlobalModifiers';
|
import { $modifiers } from 'common/hooks/useGlobalModifiers';
|
||||||
import { AnimatePresence } from 'framer-motion';
|
import { AnimatePresence } from 'framer-motion';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { InvRangeSliderMark } from './InvRangeSliderMark';
|
import { InvRangeSliderMark } from './InvRangeSliderMark';
|
||||||
import type { InvRangeSliderProps } from './types';
|
import type { InvRangeSliderProps } from './types';
|
||||||
|
|
||||||
export const InvRangeSlider = (props: InvRangeSliderProps) => {
|
export const InvRangeSlider = memo(
|
||||||
|
forwardRef<InvRangeSliderProps, ChakraRangeSlider>(
|
||||||
|
(props: InvRangeSliderProps, ref) => {
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
min,
|
min,
|
||||||
@ -61,6 +63,7 @@ export const InvRangeSlider = (props: InvRangeSliderProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ChakraRangeSlider
|
<ChakraRangeSlider
|
||||||
|
ref={ref}
|
||||||
value={value}
|
value={value}
|
||||||
min={min}
|
min={min}
|
||||||
max={max}
|
max={max}
|
||||||
@ -96,14 +99,24 @@ export const InvRangeSlider = (props: InvRangeSliderProps) => {
|
|||||||
isOpen={withTooltip && (isMouseOverSlider || isChanging)}
|
isOpen={withTooltip && (isMouseOverSlider || isChanging)}
|
||||||
label={labels[0]}
|
label={labels[0]}
|
||||||
>
|
>
|
||||||
<ChakraRangeSliderThumb index={0} onDoubleClick={onReset} zIndex={0} />
|
<ChakraRangeSliderThumb
|
||||||
|
index={0}
|
||||||
|
onDoubleClick={onReset}
|
||||||
|
zIndex={0}
|
||||||
|
/>
|
||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
<InvTooltip
|
<InvTooltip
|
||||||
isOpen={withTooltip && (isMouseOverSlider || isChanging)}
|
isOpen={withTooltip && (isMouseOverSlider || isChanging)}
|
||||||
label={labels[1]}
|
label={labels[1]}
|
||||||
>
|
>
|
||||||
<ChakraRangeSliderThumb index={1} onDoubleClick={onReset} zIndex={0} />
|
<ChakraRangeSliderThumb
|
||||||
|
index={1}
|
||||||
|
onDoubleClick={onReset}
|
||||||
|
zIndex={0}
|
||||||
|
/>
|
||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
</ChakraRangeSlider>
|
</ChakraRangeSlider>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
@ -2,13 +2,10 @@ import { RangeSliderMark as ChakraRangeSliderMark } from '@chakra-ui/react';
|
|||||||
import type { InvRangeSliderMarkProps } from 'common/components/InvRangeSlider/types';
|
import type { InvRangeSliderMarkProps } from 'common/components/InvRangeSlider/types';
|
||||||
import { sliderMarkAnimationConstants } from 'common/components/InvSlider/InvSliderMark';
|
import { sliderMarkAnimationConstants } from 'common/components/InvSlider/InvSliderMark';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const InvRangeSliderMark = ({
|
export const InvRangeSliderMark = memo(
|
||||||
value,
|
({ value, label, index, total }: InvRangeSliderMarkProps) => {
|
||||||
label,
|
|
||||||
index,
|
|
||||||
total,
|
|
||||||
}: InvRangeSliderMarkProps) => {
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
return (
|
return (
|
||||||
<ChakraRangeSliderMark
|
<ChakraRangeSliderMark
|
||||||
@ -53,4 +50,7 @@ export const InvRangeSliderMark = ({
|
|||||||
{label}
|
{label}
|
||||||
</ChakraRangeSliderMark>
|
</ChakraRangeSliderMark>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
InvRangeSliderMark.displayName = 'InvRangeSliderMark';
|
||||||
|
@ -6,7 +6,7 @@ import { cloneDeep, merge } from 'lodash-es';
|
|||||||
import type { UseOverlayScrollbarsParams } from 'overlayscrollbars-react';
|
import type { UseOverlayScrollbarsParams } from 'overlayscrollbars-react';
|
||||||
import { useOverlayScrollbars } from 'overlayscrollbars-react';
|
import { useOverlayScrollbars } from 'overlayscrollbars-react';
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { memo, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import type { InvSelectOption } from './types';
|
import type { InvSelectOption } from './types';
|
||||||
|
|
||||||
@ -25,9 +25,8 @@ const osParams = merge(
|
|||||||
overlayScrollbarsParamsOverrides
|
overlayScrollbarsParamsOverrides
|
||||||
);
|
);
|
||||||
|
|
||||||
const Scrollable = (
|
const Scrollable = memo(
|
||||||
props: PropsWithChildren<{ viewport: HTMLDivElement | null }>
|
(props: PropsWithChildren<{ viewport: HTMLDivElement | null }>) => {
|
||||||
) => {
|
|
||||||
const { children, viewport } = props;
|
const { children, viewport } = props;
|
||||||
|
|
||||||
const targetRef = useRef<HTMLDivElement>(null);
|
const targetRef = useRef<HTMLDivElement>(null);
|
||||||
@ -57,13 +56,13 @@ const Scrollable = (
|
|||||||
{children}
|
{children}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const CustomMenuList = ({
|
Scrollable.displayName = 'Scrollable';
|
||||||
children,
|
|
||||||
innerRef,
|
export const CustomMenuList = memo(
|
||||||
...other
|
({ children, innerRef, ...other }: CustomMenuListProps) => {
|
||||||
}: CustomMenuListProps) => {
|
|
||||||
const [viewport, setViewport] = useState<HTMLDivElement | null>(null);
|
const [viewport, setViewport] = useState<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -80,4 +79,7 @@ export const CustomMenuList = ({
|
|||||||
</chakraComponents.MenuList>
|
</chakraComponents.MenuList>
|
||||||
</Scrollable>
|
</Scrollable>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
CustomMenuList.displayName = 'CustomMenuList';
|
||||||
|
@ -3,6 +3,7 @@ import type { GroupBase, OptionProps } from 'chakra-react-select';
|
|||||||
import { chakraComponents } from 'chakra-react-select';
|
import { chakraComponents } from 'chakra-react-select';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import type { InvSelectOption } from './types';
|
import type { InvSelectOption } from './types';
|
||||||
|
|
||||||
@ -12,7 +13,8 @@ type CustomOptionProps = OptionProps<
|
|||||||
GroupBase<InvSelectOption>
|
GroupBase<InvSelectOption>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export const CustomOption = ({ children, ...props }: CustomOptionProps) => {
|
export const CustomOption = memo(
|
||||||
|
({ children, ...props }: CustomOptionProps) => {
|
||||||
// On large lists, perf really takes a hit :/
|
// On large lists, perf really takes a hit :/
|
||||||
// This improves it drastically and doesn't seem to break anything...
|
// This improves it drastically and doesn't seem to break anything...
|
||||||
delete props.innerProps.onMouseMove;
|
delete props.innerProps.onMouseMove;
|
||||||
@ -66,4 +68,7 @@ export const CustomOption = ({ children, ...props }: CustomOptionProps) => {
|
|||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
</chakraComponents.Option>
|
</chakraComponents.Option>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
CustomOption.displayName = 'CustomOption';
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import type { InvSelectFallbackProps } from './types';
|
import type { InvSelectFallbackProps } from './types';
|
||||||
|
|
||||||
export const InvSelectFallback = (props: InvSelectFallbackProps) => (
|
export const InvSelectFallback = memo((props: InvSelectFallbackProps) => (
|
||||||
<Flex h={8} alignItems="center" justifyContent="center">
|
<Flex h={8} alignItems="center" justifyContent="center">
|
||||||
<InvText fontSize="sm" color="base.500">
|
<InvText fontSize="sm" color="base.500">
|
||||||
{props.label}
|
{props.label}
|
||||||
</InvText>
|
</InvText>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
));
|
||||||
|
|
||||||
|
InvSelectFallback.displayName = 'InvSelectFallback';
|
||||||
|
@ -4,10 +4,11 @@ import {
|
|||||||
InvAccordionItem,
|
InvAccordionItem,
|
||||||
InvAccordionPanel,
|
InvAccordionPanel,
|
||||||
} from 'common/components/InvAccordion/wrapper';
|
} from 'common/components/InvAccordion/wrapper';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import type { InvSingleAccordionProps } from './types';
|
import type { InvSingleAccordionProps } from './types';
|
||||||
|
|
||||||
export const InvSingleAccordion = (props: InvSingleAccordionProps) => {
|
export const InvSingleAccordion = memo((props: InvSingleAccordionProps) => {
|
||||||
return (
|
return (
|
||||||
<InvAccordion
|
<InvAccordion
|
||||||
allowToggle
|
allowToggle
|
||||||
@ -21,4 +22,6 @@ export const InvSingleAccordion = (props: InvSingleAccordionProps) => {
|
|||||||
</InvAccordionItem>
|
</InvAccordionItem>
|
||||||
</InvAccordion>
|
</InvAccordion>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
InvSingleAccordion.displayName = 'InvSingleAccordion';
|
||||||
|
@ -10,12 +10,12 @@ import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput'
|
|||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
import { $modifiers } from 'common/hooks/useGlobalModifiers';
|
import { $modifiers } from 'common/hooks/useGlobalModifiers';
|
||||||
import { AnimatePresence } from 'framer-motion';
|
import { AnimatePresence } from 'framer-motion';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { InvSliderMark } from './InvSliderMark';
|
import { InvSliderMark } from './InvSliderMark';
|
||||||
import type { InvFormattedMark, InvSliderProps } from './types';
|
import type { InvFormattedMark, InvSliderProps } from './types';
|
||||||
|
|
||||||
export const InvSlider = (props: InvSliderProps) => {
|
export const InvSlider = memo((props: InvSliderProps) => {
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
min,
|
min,
|
||||||
@ -112,4 +112,6 @@ export const InvSlider = (props: InvSliderProps) => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
InvSlider.displayName = 'InvSlider';
|
||||||
|
@ -3,6 +3,7 @@ import type { SystemStyleObject } from '@chakra-ui/styled-system';
|
|||||||
import type { InvSliderMarkProps } from 'common/components/InvSlider/types';
|
import type { InvSliderMarkProps } from 'common/components/InvSlider/types';
|
||||||
import type { MotionProps } from 'framer-motion';
|
import type { MotionProps } from 'framer-motion';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
const initialFirstLast: MotionProps['initial'] = { opacity: 0, y: 10 };
|
const initialFirstLast: MotionProps['initial'] = { opacity: 0, y: 10 };
|
||||||
const initialOther = { ...initialFirstLast, x: '-50%' };
|
const initialOther = { ...initialFirstLast, x: '-50%' };
|
||||||
@ -41,12 +42,8 @@ export const sliderMarkAnimationConstants = {
|
|||||||
lastMarkStyle,
|
lastMarkStyle,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const InvSliderMark = ({
|
export const InvSliderMark = memo(
|
||||||
value,
|
({ value, label, index, total }: InvSliderMarkProps) => {
|
||||||
label,
|
|
||||||
index,
|
|
||||||
total,
|
|
||||||
}: InvSliderMarkProps) => {
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
return (
|
return (
|
||||||
<ChakraSliderMark
|
<ChakraSliderMark
|
||||||
@ -91,4 +88,7 @@ export const InvSliderMark = ({
|
|||||||
{label}
|
{label}
|
||||||
</ChakraSliderMark>
|
</ChakraSliderMark>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
InvSliderMark.displayName = 'InvSliderMark';
|
||||||
|
@ -2,9 +2,10 @@ import { Spacer } from '@chakra-ui/layout';
|
|||||||
import { forwardRef, Tab as ChakraTab } from '@chakra-ui/react';
|
import { forwardRef, Tab as ChakraTab } from '@chakra-ui/react';
|
||||||
import { InvBadge } from 'common/components/InvBadge/wrapper';
|
import { InvBadge } from 'common/components/InvBadge/wrapper';
|
||||||
import type { InvTabProps } from 'common/components/InvTabs/types';
|
import type { InvTabProps } from 'common/components/InvTabs/types';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const InvTab = forwardRef<InvTabProps, typeof ChakraTab>(
|
export const InvTab = memo(
|
||||||
(props: InvTabProps, ref) => {
|
forwardRef<InvTabProps, typeof ChakraTab>((props: InvTabProps, ref) => {
|
||||||
const { children, badges, ...rest } = props;
|
const { children, badges, ...rest } = props;
|
||||||
return (
|
return (
|
||||||
<ChakraTab ref={ref} {...rest}>
|
<ChakraTab ref={ref} {...rest}>
|
||||||
@ -17,5 +18,7 @@ export const InvTab = forwardRef<InvTabProps, typeof ChakraTab>(
|
|||||||
))}
|
))}
|
||||||
</ChakraTab>
|
</ChakraTab>
|
||||||
);
|
);
|
||||||
}
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvTab.displayName = 'InvTab';
|
||||||
|
@ -2,11 +2,12 @@ import { forwardRef, Textarea as ChakraTextarea } from '@chakra-ui/react';
|
|||||||
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
import { useGlobalModifiersSetters } from 'common/hooks/useGlobalModifiers';
|
||||||
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
import { stopPastePropagation } from 'common/util/stopPastePropagation';
|
||||||
import type { KeyboardEvent } from 'react';
|
import type { KeyboardEvent } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
import type { InvTextareaProps } from './types';
|
import type { InvTextareaProps } from './types';
|
||||||
|
|
||||||
export const InvTextarea = forwardRef<InvTextareaProps, typeof ChakraTextarea>(
|
export const InvTextarea = memo(
|
||||||
|
forwardRef<InvTextareaProps, typeof ChakraTextarea>(
|
||||||
(props: InvTextareaProps, ref) => {
|
(props: InvTextareaProps, ref) => {
|
||||||
const { ...rest } = props;
|
const { ...rest } = props;
|
||||||
const { setShift } = useGlobalModifiersSetters();
|
const { setShift } = useGlobalModifiersSetters();
|
||||||
@ -26,4 +27,7 @@ export const InvTextarea = forwardRef<InvTextareaProps, typeof ChakraTextarea>(
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvTextarea.displayName = 'InvTextarea';
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { forwardRef, Tooltip as ChakraTooltip } from '@chakra-ui/react';
|
import { forwardRef, Tooltip as ChakraTooltip } from '@chakra-ui/react';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import type { InvTooltipProps } from './types';
|
import type { InvTooltipProps } from './types';
|
||||||
|
|
||||||
export const InvTooltip = forwardRef<InvTooltipProps, typeof ChakraTooltip>(
|
export const InvTooltip = memo(
|
||||||
|
forwardRef<InvTooltipProps, typeof ChakraTooltip>(
|
||||||
(props: InvTooltipProps, ref) => {
|
(props: InvTooltipProps, ref) => {
|
||||||
const { children, hasArrow = true, placement = 'top', ...rest } = props;
|
const { children, hasArrow = true, placement = 'top', ...rest } = props;
|
||||||
return (
|
return (
|
||||||
@ -16,4 +18,7 @@ export const InvTooltip = forwardRef<InvTooltipProps, typeof ChakraTooltip>(
|
|||||||
</ChakraTooltip>
|
</ChakraTooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InvTooltip.displayName = 'InvTooltip';
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaTrash } from 'react-icons/fa';
|
import { FaTrash } from 'react-icons/fa';
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ type DeleteImageButtonProps = Omit<InvIconButtonProps, 'aria-label'> & {
|
|||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteImageButton = (props: DeleteImageButtonProps) => {
|
export const DeleteImageButton = memo((props: DeleteImageButtonProps) => {
|
||||||
const { onClick, isDisabled } = props;
|
const { onClick, isDisabled } = props;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isConnected = useAppSelector((state) => state.system.isConnected);
|
const isConnected = useAppSelector((state) => state.system.isConnected);
|
||||||
@ -23,4 +24,6 @@ export const DeleteImageButton = (props: DeleteImageButtonProps) => {
|
|||||||
colorScheme="error"
|
colorScheme="error"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
DeleteImageButton.displayName = 'DeleteImageButton';
|
||||||
|
@ -8,13 +8,14 @@ import {
|
|||||||
InvModalOverlay,
|
InvModalOverlay,
|
||||||
} from 'common/components/InvModal/wrapper';
|
} from 'common/components/InvModal/wrapper';
|
||||||
import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal';
|
import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import ParamDynamicPromptsMaxPrompts from './ParamDynamicPromptsMaxPrompts';
|
import ParamDynamicPromptsMaxPrompts from './ParamDynamicPromptsMaxPrompts';
|
||||||
import ParamDynamicPromptsPreview from './ParamDynamicPromptsPreview';
|
import ParamDynamicPromptsPreview from './ParamDynamicPromptsPreview';
|
||||||
import ParamDynamicPromptsSeedBehaviour from './ParamDynamicPromptsSeedBehaviour';
|
import ParamDynamicPromptsSeedBehaviour from './ParamDynamicPromptsSeedBehaviour';
|
||||||
|
|
||||||
export const DynamicPromptsModal = () => {
|
export const DynamicPromptsModal = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isOpen, onClose } = useDynamicPromptsModal();
|
const { isOpen, onClose } = useDynamicPromptsModal();
|
||||||
|
|
||||||
@ -41,4 +42,6 @@ export const DynamicPromptsModal = () => {
|
|||||||
</InvModalContent>
|
</InvModalContent>
|
||||||
</InvModal>
|
</InvModal>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
DynamicPromptsModal.displayName = 'DynamicPromptsModal';
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal';
|
import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { BsBracesAsterisk } from 'react-icons/bs';
|
import { BsBracesAsterisk } from 'react-icons/bs';
|
||||||
|
|
||||||
export const ShowDynamicPromptsPreviewButton = () => {
|
export const ShowDynamicPromptsPreviewButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isOpen, onOpen } = useDynamicPromptsModal();
|
const { isOpen, onOpen } = useDynamicPromptsModal();
|
||||||
return (
|
return (
|
||||||
@ -19,4 +20,6 @@ export const ShowDynamicPromptsPreviewButton = () => {
|
|||||||
/>
|
/>
|
||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ShowDynamicPromptsPreviewButton.displayName = 'ShowDynamicPromptsPreviewButton';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaCode } from 'react-icons/fa';
|
import { FaCode } from 'react-icons/fa';
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ type Props = {
|
|||||||
onOpen: () => void;
|
onOpen: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AddEmbeddingButton = (props: Props) => {
|
export const AddEmbeddingButton = memo((props: Props) => {
|
||||||
const { onOpen, isOpen } = props;
|
const { onOpen, isOpen } = props;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
@ -22,4 +23,6 @@ export const AddEmbeddingButton = (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
AddEmbeddingButton.displayName = 'AddEmbeddingButton';
|
||||||
|
@ -6,9 +6,10 @@ import {
|
|||||||
} from 'common/components/InvPopover/wrapper';
|
} from 'common/components/InvPopover/wrapper';
|
||||||
import { EmbeddingSelect } from 'features/embedding/EmbeddingSelect';
|
import { EmbeddingSelect } from 'features/embedding/EmbeddingSelect';
|
||||||
import type { EmbeddingPopoverProps } from 'features/embedding/types';
|
import type { EmbeddingPopoverProps } from 'features/embedding/types';
|
||||||
|
import { memo } from 'react';
|
||||||
import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants';
|
import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants';
|
||||||
|
|
||||||
export const EmbeddingPopover = (props: EmbeddingPopoverProps) => {
|
export const EmbeddingPopover = memo((props: EmbeddingPopoverProps) => {
|
||||||
const {
|
const {
|
||||||
onSelect,
|
onSelect,
|
||||||
isOpen,
|
isOpen,
|
||||||
@ -43,4 +44,6 @@ export const EmbeddingPopover = (props: EmbeddingPopoverProps) => {
|
|||||||
</InvPopoverContent>
|
</InvPopoverContent>
|
||||||
</InvPopover>
|
</InvPopover>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
EmbeddingPopover.displayName = 'EmbeddingPopover';
|
||||||
|
@ -6,17 +6,15 @@ import { InvSelectFallback } from 'common/components/InvSelect/InvSelectFallback
|
|||||||
import { useGroupedModelInvSelect } from 'common/components/InvSelect/useGroupedModelInvSelect';
|
import { useGroupedModelInvSelect } from 'common/components/InvSelect/useGroupedModelInvSelect';
|
||||||
import type { EmbeddingSelectProps } from 'features/embedding/types';
|
import type { EmbeddingSelectProps } from 'features/embedding/types';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import type { TextualInversionModelConfigEntity } from 'services/api/endpoints/models';
|
import type { TextualInversionModelConfigEntity } from 'services/api/endpoints/models';
|
||||||
import { useGetTextualInversionModelsQuery } from 'services/api/endpoints/models';
|
import { useGetTextualInversionModelsQuery } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
const noOptionsMessage = () => t('embedding.noMatchingEmbedding');
|
const noOptionsMessage = () => t('embedding.noMatchingEmbedding');
|
||||||
|
|
||||||
export const EmbeddingSelect = ({
|
export const EmbeddingSelect = memo(
|
||||||
onSelect,
|
({ onSelect, onClose }: EmbeddingSelectProps) => {
|
||||||
onClose,
|
|
||||||
}: EmbeddingSelectProps) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const currentBaseModel = useAppSelector(
|
const currentBaseModel = useAppSelector(
|
||||||
@ -73,7 +71,10 @@ export const EmbeddingSelect = ({
|
|||||||
/>
|
/>
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
EmbeddingSelect.displayName = 'EmbeddingSelect';
|
||||||
|
|
||||||
const selectStyles: ChakraProps['sx'] = {
|
const selectStyles: ChakraProps['sx'] = {
|
||||||
w: 'full',
|
w: 'full',
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import type { InvButtonProps } from 'common/components/InvButton/types';
|
import type { InvButtonProps } from 'common/components/InvButton/types';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaSync } from 'react-icons/fa';
|
import { FaSync } from 'react-icons/fa';
|
||||||
|
|
||||||
import { useSyncModels } from './useSyncModels';
|
import { useSyncModels } from './useSyncModels';
|
||||||
|
|
||||||
export const SyncModelsButton = (props: Omit<InvButtonProps, 'children'>) => {
|
export const SyncModelsButton = memo(
|
||||||
|
(props: Omit<InvButtonProps, 'children'>) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { syncModels, isLoading } = useSyncModels();
|
const { syncModels, isLoading } = useSyncModels();
|
||||||
const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled;
|
const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled;
|
||||||
@ -26,4 +28,7 @@ export const SyncModelsButton = (props: Omit<InvButtonProps, 'children'>) => {
|
|||||||
{t('modelManager.syncModels')}
|
{t('modelManager.syncModels')}
|
||||||
</InvButton>
|
</InvButton>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SyncModelsButton.displayName = 'SyncModelsButton';
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaSync } from 'react-icons/fa';
|
import { FaSync } from 'react-icons/fa';
|
||||||
|
|
||||||
import { useSyncModels } from './useSyncModels';
|
import { useSyncModels } from './useSyncModels';
|
||||||
|
|
||||||
export const SyncModelsIconButton = (
|
export const SyncModelsIconButton = memo(
|
||||||
props: Omit<InvIconButtonProps, 'aria-label'>
|
(props: Omit<InvIconButtonProps, 'aria-label'>) => {
|
||||||
) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { syncModels, isLoading } = useSyncModels();
|
const { syncModels, isLoading } = useSyncModels();
|
||||||
const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled;
|
const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled;
|
||||||
@ -29,4 +29,7 @@ export const SyncModelsIconButton = (
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SyncModelsIconButton.displayName = 'SyncModelsIconButton';
|
||||||
|
@ -24,7 +24,7 @@ import {
|
|||||||
import { $flow } from 'features/nodes/store/reactFlowInstance';
|
import { $flow } from 'features/nodes/store/reactFlowInstance';
|
||||||
import { bumpGlobalMenuCloseTrigger } from 'features/ui/store/uiSlice';
|
import { bumpGlobalMenuCloseTrigger } from 'features/ui/store/uiSlice';
|
||||||
import type { CSSProperties, MouseEvent } from 'react';
|
import type { CSSProperties, MouseEvent } from 'react';
|
||||||
import { useCallback, useMemo, useRef } from 'react';
|
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import type {
|
import type {
|
||||||
OnConnect,
|
OnConnect,
|
||||||
@ -77,7 +77,7 @@ const selector = createMemoizedSelector(stateSelector, ({ nodes }) => {
|
|||||||
|
|
||||||
const snapGrid: [number, number] = [25, 25];
|
const snapGrid: [number, number] = [25, 25];
|
||||||
|
|
||||||
export const Flow = () => {
|
export const Flow = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const nodes = useAppSelector((state) => state.nodes.nodes);
|
const nodes = useAppSelector((state) => state.nodes.nodes);
|
||||||
const edges = useAppSelector((state) => state.nodes.edges);
|
const edges = useAppSelector((state) => state.nodes.edges);
|
||||||
@ -287,4 +287,6 @@ export const Flow = () => {
|
|||||||
<Background />
|
<Background />
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
Flow.displayName = 'Flow';
|
||||||
|
@ -5,7 +5,7 @@ import { InvControl } from 'common/components/InvControl/InvControl';
|
|||||||
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
||||||
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
||||||
import { heightChanged } from 'features/parameters/store/generationSlice';
|
import { heightChanged } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
@ -32,7 +32,7 @@ const selector = createMemoizedSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const ParamHeight = () => {
|
export const ParamHeight = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { initial, height, min, max, inputMax, step, fineStep } =
|
const { initial, height, min, max, inputMax, step, fineStep } =
|
||||||
@ -71,4 +71,6 @@ export const ParamHeight = () => {
|
|||||||
/>
|
/>
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamHeight.displayName = 'ParamHeight';
|
||||||
|
@ -6,10 +6,10 @@ import { EmbeddingPopover } from 'features/embedding/EmbeddingPopover';
|
|||||||
import { usePrompt } from 'features/embedding/usePrompt';
|
import { usePrompt } from 'features/embedding/usePrompt';
|
||||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||||
import { setNegativePrompt } from 'features/parameters/store/generationSlice';
|
import { setNegativePrompt } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ParamNegativePrompt = () => {
|
export const ParamNegativePrompt = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const prompt = useAppSelector((state) => state.generation.negativePrompt);
|
const prompt = useAppSelector((state) => state.generation.negativePrompt);
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
@ -55,4 +55,6 @@ export const ParamNegativePrompt = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</EmbeddingPopover>
|
</EmbeddingPopover>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamNegativePrompt.displayName = 'ParamNegativePrompt';
|
||||||
|
@ -8,12 +8,12 @@ import { usePrompt } from 'features/embedding/usePrompt';
|
|||||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||||
import { setPositivePrompt } from 'features/parameters/store/generationSlice';
|
import { setPositivePrompt } from 'features/parameters/store/generationSlice';
|
||||||
import { SDXLConcatButton } from 'features/sdxl/components/SDXLPrompts/SDXLConcatButton';
|
import { SDXLConcatButton } from 'features/sdxl/components/SDXLPrompts/SDXLConcatButton';
|
||||||
import { useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import type { HotkeyCallback } from 'react-hotkeys-hook';
|
import type { HotkeyCallback } from 'react-hotkeys-hook';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ParamPositivePrompt = () => {
|
export const ParamPositivePrompt = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const prompt = useAppSelector((state) => state.generation.positivePrompt);
|
const prompt = useAppSelector((state) => state.generation.positivePrompt);
|
||||||
const baseModel = useAppSelector((state) => state.generation.model)
|
const baseModel = useAppSelector((state) => state.generation.model)
|
||||||
@ -79,4 +79,6 @@ export const ParamPositivePrompt = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</EmbeddingPopover>
|
</EmbeddingPopover>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamPositivePrompt.displayName = 'ParamPositivePrompt';
|
||||||
|
@ -5,7 +5,7 @@ import { InvControl } from 'common/components/InvControl/InvControl';
|
|||||||
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
||||||
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
||||||
import { widthChanged } from 'features/parameters/store/generationSlice';
|
import { widthChanged } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
@ -31,7 +31,7 @@ const selector = createMemoizedSelector(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
export const ParamWidth = () => {
|
export const ParamWidth = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { initial, width, min, max, inputMax, step, fineStep } =
|
const { initial, width, min, max, inputMax, step, fineStep } =
|
||||||
@ -70,4 +70,6 @@ export const ParamWidth = () => {
|
|||||||
/>
|
/>
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamWidth.displayName = 'ParamWidth';
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { AspectRatioPreview } from 'common/components/AspectRatioPreview/AspectRatioPreview';
|
import { AspectRatioPreview } from 'common/components/AspectRatioPreview/AspectRatioPreview';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const AspectRatioPreviewWrapper = () => {
|
export const AspectRatioPreviewWrapper = memo(() => {
|
||||||
const width = useAppSelector((state) => state.generation.width);
|
const width = useAppSelector((state) => state.generation.width);
|
||||||
const height = useAppSelector((state) => state.generation.height);
|
const height = useAppSelector((state) => state.generation.height);
|
||||||
|
|
||||||
return <AspectRatioPreview width={width} height={height} />;
|
return <AspectRatioPreview width={width} height={height} />;
|
||||||
};
|
});
|
||||||
|
|
||||||
|
AspectRatioPreviewWrapper.displayName = 'AspectRatioPreviewWrapper';
|
||||||
|
@ -7,14 +7,14 @@ import type { InvSelectOption } from 'common/components/InvSelect/types';
|
|||||||
import { ASPECT_RATIO_OPTIONS } from 'features/parameters/components/ImageSize/constants';
|
import { ASPECT_RATIO_OPTIONS } from 'features/parameters/components/ImageSize/constants';
|
||||||
import { isAspectRatioID } from 'features/parameters/components/ImageSize/types';
|
import { isAspectRatioID } from 'features/parameters/components/ImageSize/types';
|
||||||
import { aspectRatioSelected } from 'features/parameters/store/generationSlice';
|
import { aspectRatioSelected } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { LockAspectRatioButton } from './LockAspectRatioButton';
|
import { LockAspectRatioButton } from './LockAspectRatioButton';
|
||||||
import { SetOptimalSizeButton } from './SetOptimalSizeButton';
|
import { SetOptimalSizeButton } from './SetOptimalSizeButton';
|
||||||
import { SwapDimensionsButton } from './SwapDimensionsButton';
|
import { SwapDimensionsButton } from './SwapDimensionsButton';
|
||||||
|
|
||||||
export const AspectRatioSelect = () => {
|
export const AspectRatioSelect = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const aspectRatioID = useAppSelector(
|
const aspectRatioID = useAppSelector(
|
||||||
@ -49,6 +49,8 @@ export const AspectRatioSelect = () => {
|
|||||||
<SetOptimalSizeButton />
|
<SetOptimalSizeButton />
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
AspectRatioSelect.displayName = 'AspectRatioSelect';
|
||||||
|
|
||||||
const selectStyles: SystemStyleObject = { minW: 48 };
|
const selectStyles: SystemStyleObject = { minW: 48 };
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { isLockedToggled } from 'features/parameters/store/generationSlice';
|
import { isLockedToggled } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaLock, FaLockOpen } from 'react-icons/fa6';
|
import { FaLock, FaLockOpen } from 'react-icons/fa6';
|
||||||
|
|
||||||
export const LockAspectRatioButton = () => {
|
export const LockAspectRatioButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isLocked = useAppSelector(
|
const isLocked = useAppSelector(
|
||||||
@ -24,4 +24,6 @@ export const LockAspectRatioButton = () => {
|
|||||||
icon={isLocked ? <FaLock /> : <FaLockOpen />}
|
icon={isLocked ? <FaLock /> : <FaLockOpen />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
LockAspectRatioButton.displayName = 'LockAspectRatioButton';
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { sizeReset } from 'features/parameters/store/generationSlice';
|
import { sizeReset } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { IoSparkles } from 'react-icons/io5';
|
import { IoSparkles } from 'react-icons/io5';
|
||||||
|
|
||||||
export const SetOptimalSizeButton = () => {
|
export const SetOptimalSizeButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const optimalDimension = useAppSelector((state) =>
|
const optimalDimension = useAppSelector((state) =>
|
||||||
state.generation.model?.base_model === 'sdxl' ? 1024 : 512
|
state.generation.model?.base_model === 'sdxl' ? 1024 : 512
|
||||||
@ -24,4 +24,6 @@ export const SetOptimalSizeButton = () => {
|
|||||||
icon={<IoSparkles />}
|
icon={<IoSparkles />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SetOptimalSizeButton.displayName = 'SetOptimalSizeButton';
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { dimensionsSwapped } from 'features/parameters/store/generationSlice';
|
import { dimensionsSwapped } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { IoSwapVertical } from 'react-icons/io5';
|
import { IoSwapVertical } from 'react-icons/io5';
|
||||||
|
|
||||||
export const SwapDimensionsButton = () => {
|
export const SwapDimensionsButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
@ -20,4 +20,6 @@ export const SwapDimensionsButton = () => {
|
|||||||
icon={<IoSwapVertical />}
|
icon={<IoSwapVertical />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SwapDimensionsButton.displayName = 'SwapDimensionsButton';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Flex } from '@chakra-ui/layout';
|
import { Flex } from '@chakra-ui/layout';
|
||||||
import type { PropsWithChildren } from 'react';
|
import { memo, type PropsWithChildren } from 'react';
|
||||||
|
|
||||||
export const PromptOverlayButtonWrapper = (props: PropsWithChildren) => (
|
export const PromptOverlayButtonWrapper = memo((props: PropsWithChildren) => (
|
||||||
<Flex
|
<Flex
|
||||||
pos="absolute"
|
pos="absolute"
|
||||||
insetBlockStart={0}
|
insetBlockStart={0}
|
||||||
@ -14,4 +14,6 @@ export const PromptOverlayButtonWrapper = (props: PropsWithChildren) => (
|
|||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
));
|
||||||
|
|
||||||
|
PromptOverlayButtonWrapper.displayName = 'PromptOverlayButtonWrapper';
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
||||||
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const Prompts = () => {
|
export const Prompts = memo(() => {
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" gap={2}>
|
<Flex flexDir="column" gap={2}>
|
||||||
<ParamPositivePrompt />
|
<ParamPositivePrompt />
|
||||||
<ParamNegativePrompt />
|
<ParamNegativePrompt />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
Prompts.displayName = 'Prompts';
|
||||||
|
@ -3,10 +3,10 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
||||||
import { setSeed } from 'features/parameters/store/generationSlice';
|
import { setSeed } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ParamSeedNumberInput = () => {
|
export const ParamSeedNumberInput = memo(() => {
|
||||||
const seed = useAppSelector((state) => state.generation.seed);
|
const seed = useAppSelector((state) => state.generation.seed);
|
||||||
const shouldRandomizeSeed = useAppSelector(
|
const shouldRandomizeSeed = useAppSelector(
|
||||||
(state) => state.generation.shouldRandomizeSeed
|
(state) => state.generation.shouldRandomizeSeed
|
||||||
@ -34,4 +34,6 @@ export const ParamSeedNumberInput = () => {
|
|||||||
/>
|
/>
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamSeedNumberInput.displayName = 'ParamSeedNumberInput';
|
||||||
|
@ -4,10 +4,10 @@ import { InvControl } from 'common/components/InvControl/InvControl';
|
|||||||
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
||||||
import { setShouldRandomizeSeed } from 'features/parameters/store/generationSlice';
|
import { setShouldRandomizeSeed } from 'features/parameters/store/generationSlice';
|
||||||
import type { ChangeEvent } from 'react';
|
import type { ChangeEvent } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ParamSeedRandomize = () => {
|
export const ParamSeedRandomize = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -29,4 +29,6 @@ export const ParamSeedRandomize = () => {
|
|||||||
/>
|
/>
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamSeedRandomize.displayName = 'ParamSeedRandomize';
|
||||||
|
@ -4,11 +4,11 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import randomInt from 'common/util/randomInt';
|
import randomInt from 'common/util/randomInt';
|
||||||
import { setSeed } from 'features/parameters/store/generationSlice';
|
import { setSeed } from 'features/parameters/store/generationSlice';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaShuffle } from 'react-icons/fa6';
|
import { FaShuffle } from 'react-icons/fa6';
|
||||||
|
|
||||||
export const ParamSeedShuffle = () => {
|
export const ParamSeedShuffle = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const shouldRandomizeSeed = useAppSelector(
|
const shouldRandomizeSeed = useAppSelector(
|
||||||
(state: RootState) => state.generation.shouldRandomizeSeed
|
(state: RootState) => state.generation.shouldRandomizeSeed
|
||||||
@ -31,4 +31,6 @@ export const ParamSeedShuffle = () => {
|
|||||||
{t('parameters.shuffle')}
|
{t('parameters.shuffle')}
|
||||||
</InvButton>
|
</InvButton>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamSeedShuffle.displayName = 'ParamSeedShuffle';
|
||||||
|
@ -6,7 +6,7 @@ import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
|||||||
import { useGroupedModelInvSelect } from 'common/components/InvSelect/useGroupedModelInvSelect';
|
import { useGroupedModelInvSelect } from 'common/components/InvSelect/useGroupedModelInvSelect';
|
||||||
import { vaeSelected } from 'features/parameters/store/generationSlice';
|
import { vaeSelected } from 'features/parameters/store/generationSlice';
|
||||||
import { pick } from 'lodash-es';
|
import { pick } from 'lodash-es';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import type { VaeModelConfigEntity } from 'services/api/endpoints/models';
|
import type { VaeModelConfigEntity } from 'services/api/endpoints/models';
|
||||||
import { useGetVaeModelsQuery } from 'services/api/endpoints/models';
|
import { useGetVaeModelsQuery } from 'services/api/endpoints/models';
|
||||||
@ -60,4 +60,4 @@ const ParamVAEModelSelect = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ParamVAEModelSelect;
|
export default memo(ParamVAEModelSelect);
|
||||||
|
@ -8,7 +8,7 @@ import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput'
|
|||||||
import type { InvNumberInputFieldProps } from 'common/components/InvNumberInput/types';
|
import type { InvNumberInputFieldProps } from 'common/components/InvNumberInput/types';
|
||||||
import { setIterations } from 'features/parameters/store/generationSlice';
|
import { setIterations } from 'features/parameters/store/generationSlice';
|
||||||
import { useQueueBack } from 'features/queue/hooks/useQueueBack';
|
import { useQueueBack } from 'features/queue/hooks/useQueueBack';
|
||||||
import { useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { IoSparkles } from 'react-icons/io5';
|
import { IoSparkles } from 'react-icons/io5';
|
||||||
|
|
||||||
import { QueueButtonTooltip } from './QueueButtonTooltip';
|
import { QueueButtonTooltip } from './QueueButtonTooltip';
|
||||||
@ -40,7 +40,7 @@ const selector = createMemoizedSelector([stateSelector], (state) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const InvokeQueueBackButton = () => {
|
export const InvokeQueueBackButton = memo(() => {
|
||||||
const { queueBack, isLoading, isDisabled } = useQueueBack();
|
const { queueBack, isLoading, isDisabled } = useQueueBack();
|
||||||
const { iterations, step, fineStep } = useAppSelector(selector);
|
const { iterations, step, fineStep } = useAppSelector(selector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
@ -89,4 +89,6 @@ export const InvokeQueueBackButton = () => {
|
|||||||
</InvButton>
|
</InvButton>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
InvokeQueueBackButton.displayName = 'InvokeQueueBackButton';
|
||||||
|
@ -9,12 +9,13 @@ import { useCancelCurrentQueueItem } from 'features/queue/hooks/useCancelCurrent
|
|||||||
import { usePauseProcessor } from 'features/queue/hooks/usePauseProcessor';
|
import { usePauseProcessor } from 'features/queue/hooks/usePauseProcessor';
|
||||||
import { useResumeProcessor } from 'features/queue/hooks/useResumeProcessor';
|
import { useResumeProcessor } from 'features/queue/hooks/useResumeProcessor';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaPause, FaPlay, FaTimes } from 'react-icons/fa';
|
import { FaPause, FaPlay, FaTimes } from 'react-icons/fa';
|
||||||
import { FaList } from 'react-icons/fa6';
|
import { FaList } from 'react-icons/fa6';
|
||||||
import { useGetQueueStatusQuery } from 'services/api/endpoints/queue';
|
import { useGetQueueStatusQuery } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
export const QueueActionsMenuButton = () => {
|
export const QueueActionsMenuButton = memo(() => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isPauseEnabled = useFeatureStatus('pauseQueue').isFeatureEnabled;
|
const isPauseEnabled = useFeatureStatus('pauseQueue').isFeatureEnabled;
|
||||||
@ -100,4 +101,6 @@ export const QueueActionsMenuButton = () => {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
QueueActionsMenuButton.displayName = 'QueueActionsMenuButton';
|
||||||
|
@ -4,6 +4,7 @@ import ClearQueueButton from 'features/queue/components/ClearQueueButton';
|
|||||||
import QueueFrontButton from 'features/queue/components/QueueFrontButton';
|
import QueueFrontButton from 'features/queue/components/QueueFrontButton';
|
||||||
import ProgressBar from 'features/system/components/ProgressBar';
|
import ProgressBar from 'features/system/components/ProgressBar';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import { InvokeQueueBackButton } from './InvokeQueueBackButton';
|
import { InvokeQueueBackButton } from './InvokeQueueBackButton';
|
||||||
import { QueueActionsMenuButton } from './QueueActionsMenuButton';
|
import { QueueActionsMenuButton } from './QueueActionsMenuButton';
|
||||||
@ -35,7 +36,7 @@ const QueueControls = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default QueueControls;
|
export default memo(QueueControls);
|
||||||
|
|
||||||
// const QueueCounts = () => {
|
// const QueueCounts = () => {
|
||||||
// const { t } = useTranslation();
|
// const { t } = useTranslation();
|
||||||
|
@ -6,11 +6,11 @@ import { EmbeddingPopover } from 'features/embedding/EmbeddingPopover';
|
|||||||
import { usePrompt } from 'features/embedding/usePrompt';
|
import { usePrompt } from 'features/embedding/usePrompt';
|
||||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||||
import { setNegativeStylePromptSDXL } from 'features/sdxl/store/sdxlSlice';
|
import { setNegativeStylePromptSDXL } from 'features/sdxl/store/sdxlSlice';
|
||||||
import { useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ParamSDXLNegativeStylePrompt = () => {
|
export const ParamSDXLNegativeStylePrompt = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const prompt = useAppSelector((state) => state.sdxl.negativeStylePrompt);
|
const prompt = useAppSelector((state) => state.sdxl.negativeStylePrompt);
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
@ -65,4 +65,6 @@ export const ParamSDXLNegativeStylePrompt = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</EmbeddingPopover>
|
</EmbeddingPopover>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamSDXLNegativeStylePrompt.displayName = 'ParamSDXLNegativeStylePrompt';
|
||||||
|
@ -6,10 +6,10 @@ import { EmbeddingPopover } from 'features/embedding/EmbeddingPopover';
|
|||||||
import { usePrompt } from 'features/embedding/usePrompt';
|
import { usePrompt } from 'features/embedding/usePrompt';
|
||||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||||
import { setPositiveStylePromptSDXL } from 'features/sdxl/store/sdxlSlice';
|
import { setPositiveStylePromptSDXL } from 'features/sdxl/store/sdxlSlice';
|
||||||
import { useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ParamSDXLPositiveStylePrompt = () => {
|
export const ParamSDXLPositiveStylePrompt = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const prompt = useAppSelector((state) => state.sdxl.positiveStylePrompt);
|
const prompt = useAppSelector((state) => state.sdxl.positiveStylePrompt);
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
@ -55,4 +55,6 @@ export const ParamSDXLPositiveStylePrompt = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</EmbeddingPopover>
|
</EmbeddingPopover>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ParamSDXLPositiveStylePrompt.displayName = 'ParamSDXLPositiveStylePrompt';
|
||||||
|
@ -2,11 +2,11 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
import { setShouldConcatSDXLStylePrompt } from 'features/sdxl/store/sdxlSlice';
|
import { setShouldConcatSDXLStylePrompt } from 'features/sdxl/store/sdxlSlice';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaLink, FaUnlink } from 'react-icons/fa';
|
import { FaLink, FaUnlink } from 'react-icons/fa';
|
||||||
|
|
||||||
export const SDXLConcatButton = () => {
|
export const SDXLConcatButton = memo(() => {
|
||||||
const shouldConcatSDXLStylePrompt = useAppSelector(
|
const shouldConcatSDXLStylePrompt = useAppSelector(
|
||||||
(state) => state.sdxl.shouldConcatSDXLStylePrompt
|
(state) => state.sdxl.shouldConcatSDXLStylePrompt
|
||||||
);
|
);
|
||||||
@ -38,4 +38,6 @@ export const SDXLConcatButton = () => {
|
|||||||
/>
|
/>
|
||||||
</InvTooltip>
|
</InvTooltip>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SDXLConcatButton.displayName = 'SDXLConcatButton';
|
||||||
|
@ -2,11 +2,12 @@ import { Flex } from '@chakra-ui/react';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
||||||
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
import { ParamSDXLNegativeStylePrompt } from './ParamSDXLNegativeStylePrompt';
|
import { ParamSDXLNegativeStylePrompt } from './ParamSDXLNegativeStylePrompt';
|
||||||
import { ParamSDXLPositiveStylePrompt } from './ParamSDXLPositiveStylePrompt';
|
import { ParamSDXLPositiveStylePrompt } from './ParamSDXLPositiveStylePrompt';
|
||||||
|
|
||||||
export const SDXLPrompts = () => {
|
export const SDXLPrompts = memo(() => {
|
||||||
const shouldConcatSDXLStylePrompt = useAppSelector(
|
const shouldConcatSDXLStylePrompt = useAppSelector(
|
||||||
(state) => state.sdxl.shouldConcatSDXLStylePrompt
|
(state) => state.sdxl.shouldConcatSDXLStylePrompt
|
||||||
);
|
);
|
||||||
@ -18,4 +19,6 @@ export const SDXLPrompts = () => {
|
|||||||
{!shouldConcatSDXLStylePrompt && <ParamSDXLNegativeStylePrompt />}
|
{!shouldConcatSDXLStylePrompt && <ParamSDXLNegativeStylePrompt />}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SDXLPrompts.displayName = 'SDXLPrompts';
|
||||||
|
@ -8,6 +8,7 @@ import ParamSeamlessXAxis from 'features/parameters/components/Seamless/ParamSea
|
|||||||
import ParamSeamlessYAxis from 'features/parameters/components/Seamless/ParamSeamlessYAxis';
|
import ParamSeamlessYAxis from 'features/parameters/components/Seamless/ParamSeamlessYAxis';
|
||||||
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
|
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
|
||||||
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
|
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const labelProps: InvLabelProps = {
|
const labelProps: InvLabelProps = {
|
||||||
@ -18,7 +19,7 @@ const labelProps2: InvLabelProps = {
|
|||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AdvancedSettingsAccordion = () => {
|
export const AdvancedSettingsAccordion = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -41,4 +42,6 @@ export const AdvancedSettingsAccordion = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</InvSingleAccordion>
|
</InvSingleAccordion>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
AdvancedSettingsAccordion.displayName = 'AdvancedSettingsAccordion';
|
||||||
|
@ -21,6 +21,7 @@ import ParamScheduler from 'features/parameters/components/Core/ParamScheduler';
|
|||||||
import ParamSteps from 'features/parameters/components/Core/ParamSteps';
|
import ParamSteps from 'features/parameters/components/Core/ParamSteps';
|
||||||
import ParamMainModelSelect from 'features/parameters/components/MainModel/ParamMainModelSelect';
|
import ParamMainModelSelect from 'features/parameters/components/MainModel/ParamMainModelSelect';
|
||||||
import { size, truncate } from 'lodash-es';
|
import { size, truncate } from 'lodash-es';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const labelProps: InvLabelProps = {
|
const labelProps: InvLabelProps = {
|
||||||
@ -43,7 +44,7 @@ const badgesSelector = createMemoizedSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const GenerationSettingsAccordion = () => {
|
export const GenerationSettingsAccordion = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { loraTabBadges, accordionBadges } = useAppSelector(badgesSelector);
|
const { loraTabBadges, accordionBadges } = useAppSelector(badgesSelector);
|
||||||
|
|
||||||
@ -86,4 +87,6 @@ export const GenerationSettingsAccordion = () => {
|
|||||||
</InvTabs>
|
</InvTabs>
|
||||||
</InvSingleAccordion>
|
</InvSingleAccordion>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
GenerationSettingsAccordion.displayName = 'GenerationSettingsAccordion';
|
||||||
|
@ -23,6 +23,7 @@ import { ParamSeedRandomize } from 'features/parameters/components/Seed/ParamSee
|
|||||||
import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle';
|
import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
@ -49,7 +50,7 @@ const scalingLabelProps: InvLabelProps = {
|
|||||||
w: '4.5rem',
|
w: '4.5rem',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ImageSettingsAccordion = () => {
|
export const ImageSettingsAccordion = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { badges, activeTabName } = useAppSelector(selector);
|
const { badges, activeTabName } = useAppSelector(selector);
|
||||||
|
|
||||||
@ -95,9 +96,11 @@ export const ImageSettingsAccordion = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</InvSingleAccordion>
|
</InvSingleAccordion>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
const WidthHeight = (props: { activeTabName: InvokeTabName }) => {
|
ImageSettingsAccordion.displayName = 'ImageSettingsAccordion';
|
||||||
|
|
||||||
|
const WidthHeight = memo((props: { activeTabName: InvokeTabName }) => {
|
||||||
if (props.activeTabName === 'unifiedCanvas') {
|
if (props.activeTabName === 'unifiedCanvas') {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -113,4 +116,6 @@ const WidthHeight = (props: { activeTabName: InvokeTabName }) => {
|
|||||||
<ParamHeight />
|
<ParamHeight />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
WidthHeight.displayName = 'WidthHeight';
|
||||||
|
@ -5,10 +5,10 @@ import type { InvSelectOnChange } from 'common/components/InvSelect/types';
|
|||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import { languageChanged } from 'features/system/store/systemSlice';
|
import { languageChanged } from 'features/system/store/systemSlice';
|
||||||
import { isLanguage } from 'features/system/store/types';
|
import { isLanguage } from 'features/system/store/types';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const SettingsLanguageSelect = () => {
|
export const SettingsLanguageSelect = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const language = useAppSelector((state) => state.system.language);
|
const language = useAppSelector((state) => state.system.language);
|
||||||
@ -58,4 +58,6 @@ export const SettingsLanguageSelect = () => {
|
|||||||
<InvSelect value={value} options={options} onChange={onChange} />
|
<InvSelect value={value} options={options} onChange={onChange} />
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SettingsLanguageSelect.displayName = 'SettingsLanguageSelect';
|
||||||
|
@ -4,10 +4,10 @@ import { InvControl } from 'common/components/InvControl/InvControl';
|
|||||||
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
||||||
import type { InvSelectOnChange } from 'common/components/InvSelect/types';
|
import type { InvSelectOnChange } from 'common/components/InvSelect/types';
|
||||||
import { consoleLogLevelChanged } from 'features/system/store/systemSlice';
|
import { consoleLogLevelChanged } from 'features/system/store/systemSlice';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const SettingsLogLevelSelect = () => {
|
export const SettingsLogLevelSelect = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const consoleLogLevel = useAppSelector(
|
const consoleLogLevel = useAppSelector(
|
||||||
@ -43,4 +43,6 @@ export const SettingsLogLevelSelect = () => {
|
|||||||
<InvSelect value={value} options={options} onChange={onChange} />
|
<InvSelect value={value} options={options} onChange={onChange} />
|
||||||
</InvControl>
|
</InvControl>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SettingsLogLevelSelect.displayName = 'SettingsLogLevelSelect';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user