mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): use primitive style props or memoized sx objects
This commit is contained in:
committed by
Kent Keirsey
parent
83049a3a5b
commit
4f2930412e
@ -20,14 +20,12 @@ const NodeEditor = () => {
|
||||
return (
|
||||
<Flex
|
||||
layerStyle="first"
|
||||
sx={{
|
||||
position: 'relative',
|
||||
width: 'full',
|
||||
height: 'full',
|
||||
borderRadius: 'base',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
position="relative"
|
||||
width="full"
|
||||
height="full"
|
||||
borderRadius="base"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<AnimatePresence>
|
||||
{isReady && (
|
||||
@ -71,15 +69,13 @@ const NodeEditor = () => {
|
||||
>
|
||||
<Flex
|
||||
layerStyle="first"
|
||||
sx={{
|
||||
position: 'relative',
|
||||
width: 'full',
|
||||
height: 'full',
|
||||
borderRadius: 'base',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
position="relative"
|
||||
width="full"
|
||||
height="full"
|
||||
borderRadius="base"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
pointerEvents="none"
|
||||
>
|
||||
<IAINoContentFallback
|
||||
label={t('nodes.loadingNodes')}
|
||||
|
@ -230,9 +230,6 @@ const AddNodePopover = () => {
|
||||
onChange={onChange}
|
||||
onMenuClose={onClose}
|
||||
onKeyDown={onKeyDown}
|
||||
sx={{
|
||||
width: 'full',
|
||||
}}
|
||||
/>
|
||||
</InvPopoverBody>
|
||||
</InvPopoverContent>
|
||||
|
@ -65,19 +65,15 @@ const InvocationCollapsedEdge = ({
|
||||
{data?.count && data.count > 1 && (
|
||||
<EdgeLabelRenderer>
|
||||
<Flex
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
||||
}}
|
||||
position="absolute"
|
||||
transform={`translate(-50%, -50%) translate(${labelX}px,${labelY}px)`}
|
||||
className="nodrag nopan"
|
||||
>
|
||||
<Badge
|
||||
variant="solid"
|
||||
sx={{
|
||||
bg: 'base.500',
|
||||
opacity: isSelected ? 0.8 : 0.5,
|
||||
boxShadow: 'base',
|
||||
}}
|
||||
bg="base.500"
|
||||
opacity={isSelected ? 0.8 : 0.5}
|
||||
boxShadow="base"
|
||||
>
|
||||
{data.count}
|
||||
</Badge>
|
||||
|
@ -34,12 +34,10 @@ const CurrentImageNode = (props: NodeProps) => {
|
||||
<Wrapper nodeProps={props}>
|
||||
<Image
|
||||
src={progressImage.dataURL}
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
objectFit: 'contain',
|
||||
borderRadius: 'base',
|
||||
}}
|
||||
w="full"
|
||||
h="full"
|
||||
objectFit="contain"
|
||||
borderRadius="base"
|
||||
/>
|
||||
</Wrapper>
|
||||
);
|
||||
@ -83,38 +81,26 @@ const Wrapper = (props: PropsWithChildren<{ nodeProps: NodeProps }>) => {
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
className={DRAG_HANDLE_CLASSNAME}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
position="relative"
|
||||
flexDirection="column"
|
||||
>
|
||||
<Flex
|
||||
layerStyle="nodeHeader"
|
||||
sx={{
|
||||
borderTopRadius: 'base',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
h: 8,
|
||||
}}
|
||||
borderTopRadius="base"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
h={8}
|
||||
>
|
||||
<InvText
|
||||
sx={{
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'semibold',
|
||||
color: 'base.200',
|
||||
}}
|
||||
>
|
||||
<InvText fontSize="sm" fontWeight="semibold" color="base.200">
|
||||
{t('nodes.currentImage')}
|
||||
</InvText>
|
||||
</Flex>
|
||||
<Flex
|
||||
layerStyle="nodeBody"
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
borderBottomRadius: 'base',
|
||||
p: 2,
|
||||
}}
|
||||
w="full"
|
||||
h="full"
|
||||
borderBottomRadius="base"
|
||||
p={2}
|
||||
>
|
||||
{props.children}
|
||||
{isHovering && (
|
||||
|
@ -38,16 +38,14 @@ const InvocationNode = ({ nodeId, isOpen, label, type, selected }: Props) => {
|
||||
<>
|
||||
<Flex
|
||||
layerStyle="nodeBody"
|
||||
sx={{
|
||||
flexDirection: 'column',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
py: 2,
|
||||
gap: 1,
|
||||
borderBottomRadius: withFooter ? 0 : 'base',
|
||||
}}
|
||||
flexDirection="column"
|
||||
w="full"
|
||||
h="full"
|
||||
py={2}
|
||||
gap={1}
|
||||
borderBottomRadius={withFooter ? 0 : 'base'}
|
||||
>
|
||||
<Flex sx={{ flexDir: 'column', px: 2, w: 'full', h: 'full' }}>
|
||||
<Flex flexDir="column" px={2} w="full" h="full">
|
||||
<Grid gridTemplateColumns="1fr auto" gridAutoRows="1fr">
|
||||
{inputConnectionFieldNames.map((fieldName, i) => (
|
||||
<GridItem
|
||||
|
@ -26,11 +26,9 @@ const InvocationNodeClassificationIcon = ({ nodeId }: Props) => {
|
||||
>
|
||||
<Icon
|
||||
as={getIcon(classification)}
|
||||
sx={{
|
||||
display: 'block',
|
||||
boxSize: 4,
|
||||
color: 'base.400',
|
||||
}}
|
||||
display="block"
|
||||
boxSize={4}
|
||||
color="base.400"
|
||||
/>
|
||||
</InvTooltip>
|
||||
);
|
||||
|
@ -18,14 +18,12 @@ const InvocationNodeFooter = ({ nodeId }: Props) => {
|
||||
<Flex
|
||||
className={DRAG_HANDLE_CLASSNAME}
|
||||
layerStyle="nodeFooter"
|
||||
sx={{
|
||||
w: 'full',
|
||||
borderBottomRadius: 'base',
|
||||
px: 2,
|
||||
py: 0,
|
||||
h: 8,
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
w="full"
|
||||
borderBottomRadius="base"
|
||||
px={2}
|
||||
py={0}
|
||||
h={8}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
{isCacheEnabled && <UseCacheCheckbox nodeId={nodeId} />}
|
||||
{hasImageOutput && <SaveToGalleryCheckbox nodeId={nodeId} />}
|
||||
|
@ -20,15 +20,13 @@ const InvocationNodeHeader = ({ nodeId, isOpen }: Props) => {
|
||||
return (
|
||||
<Flex
|
||||
layerStyle="nodeHeader"
|
||||
sx={{
|
||||
borderTopRadius: 'base',
|
||||
borderBottomRadius: isOpen ? 0 : 'base',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
h: 8,
|
||||
textAlign: 'center',
|
||||
color: 'base.200',
|
||||
}}
|
||||
borderTopRadius="base"
|
||||
borderBottomRadius={isOpen ? 0 : 'base'}
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
h={8}
|
||||
textAlign="center"
|
||||
color="base.200"
|
||||
>
|
||||
<NodeCollapseButton nodeId={nodeId} isOpen={isOpen} />
|
||||
<InvocationNodeClassificationIcon nodeId={nodeId} />
|
||||
|
@ -25,12 +25,10 @@ const InvocationNodeInfoIcon = ({ nodeId }: Props) => {
|
||||
>
|
||||
<Icon
|
||||
as={FaInfoCircle}
|
||||
sx={{
|
||||
display: 'block',
|
||||
boxSize: 4,
|
||||
w: 8,
|
||||
color: needsUpdate ? 'error.400' : 'base.400',
|
||||
}}
|
||||
display="block"
|
||||
boxSize={4}
|
||||
w={8}
|
||||
color={needsUpdate ? 'error.400' : 'base.400'}
|
||||
/>
|
||||
</InvTooltip>
|
||||
);
|
||||
@ -66,7 +64,7 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
|
||||
if (!data.version) {
|
||||
return (
|
||||
<InvText as="span" sx={{ color: 'error.500' }}>
|
||||
<InvText as="span" color="error.500">
|
||||
{t('nodes.versionUnknown')}
|
||||
</InvText>
|
||||
);
|
||||
@ -74,7 +72,7 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
|
||||
if (!nodeTemplate.version) {
|
||||
return (
|
||||
<InvText as="span" sx={{ color: 'error.500' }}>
|
||||
<InvText as="span" color="error.500">
|
||||
{t('nodes.version')} {data.version} ({t('nodes.unknownTemplate')})
|
||||
</InvText>
|
||||
);
|
||||
@ -82,7 +80,7 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
|
||||
if (compare(data.version, nodeTemplate.version, '<')) {
|
||||
return (
|
||||
<InvText as="span" sx={{ color: 'error.500' }}>
|
||||
<InvText as="span" color="error.500">
|
||||
{t('nodes.version')} {data.version} ({t('nodes.updateNode')})
|
||||
</InvText>
|
||||
);
|
||||
@ -90,7 +88,7 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
|
||||
if (compare(data.version, nodeTemplate.version, '>')) {
|
||||
return (
|
||||
<InvText as="span" sx={{ color: 'error.500' }}>
|
||||
<InvText as="span" color="error.500">
|
||||
{t('nodes.version')} {data.version} ({t('nodes.updateApp')})
|
||||
</InvText>
|
||||
);
|
||||
@ -104,16 +102,12 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
}, [data, nodeTemplate, t]);
|
||||
|
||||
if (!isInvocationNodeData(data)) {
|
||||
return (
|
||||
<InvText sx={{ fontWeight: 'semibold' }}>
|
||||
{t('nodes.unknownNode')}
|
||||
</InvText>
|
||||
);
|
||||
return <InvText fontWeight="semibold">{t('nodes.unknownNode')}</InvText>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex sx={{ flexDir: 'column' }}>
|
||||
<InvText as="span" sx={{ fontWeight: 'semibold' }}>
|
||||
<Flex flexDir="column">
|
||||
<InvText as="span" fontWeight="semibold">
|
||||
{title}
|
||||
</InvText>
|
||||
{nodeTemplate?.nodePack && (
|
||||
@ -121,7 +115,7 @@ const TooltipContent = memo(({ nodeId }: { nodeId: string }) => {
|
||||
{t('nodes.nodePack')}: {nodeTemplate.nodePack}
|
||||
</InvText>
|
||||
)}
|
||||
<InvText sx={{ opacity: 0.7, fontStyle: 'oblique 5deg' }}>
|
||||
<InvText opacity={0.7} fontStyle="oblique 5deg">
|
||||
{nodeTemplate?.description}
|
||||
</InvText>
|
||||
{versionComponent}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { SystemStyleObject } from '@chakra-ui/react';
|
||||
import { Badge, CircularProgress, Flex, Icon, Image } from '@chakra-ui/react';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
@ -16,7 +17,7 @@ type Props = {
|
||||
};
|
||||
|
||||
const iconBoxSize = 3;
|
||||
const circleStyles = {
|
||||
const circleStyles: SystemStyleObject = {
|
||||
circle: {
|
||||
transitionProperty: 'none',
|
||||
transitionDuration: '0s',
|
||||
@ -47,12 +48,10 @@ const InvocationNodeStatusIndicator = ({ nodeId }: Props) => {
|
||||
>
|
||||
<Flex
|
||||
className={DRAG_HANDLE_CLASSNAME}
|
||||
sx={{
|
||||
w: 5,
|
||||
h: 'full',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
w={5}
|
||||
h="full"
|
||||
alignItems="center"
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<StatusIcon nodeExecutionState={nodeExecutionState} />
|
||||
</Flex>
|
||||
@ -75,16 +74,16 @@ const TooltipLabel = memo(({ nodeExecutionState }: TooltipLabelProps) => {
|
||||
if (status === zNodeStatus.enum.IN_PROGRESS) {
|
||||
if (progressImage) {
|
||||
return (
|
||||
<Flex sx={{ pos: 'relative', pt: 1.5, pb: 0.5 }}>
|
||||
<Flex pos="relative" pt={1.5} pb={0.5}>
|
||||
<Image
|
||||
src={progressImage.dataURL}
|
||||
sx={{ w: 32, h: 32, borderRadius: 'base', objectFit: 'contain' }}
|
||||
w={32}
|
||||
h={32}
|
||||
borderRadius="base"
|
||||
objectFit="contain"
|
||||
/>
|
||||
{progress !== null && (
|
||||
<Badge
|
||||
variant="solid"
|
||||
sx={{ pos: 'absolute', top: 2.5, insetInlineEnd: 1 }}
|
||||
>
|
||||
<Badge variant="solid" pos="absolute" top={2.5} insetInlineEnd={1}>
|
||||
{Math.round(progress * 100)}%
|
||||
</Badge>
|
||||
)}
|
||||
@ -123,15 +122,7 @@ type StatusIconProps = {
|
||||
const StatusIcon = memo((props: StatusIconProps) => {
|
||||
const { progress, status } = props.nodeExecutionState;
|
||||
if (status === zNodeStatus.enum.PENDING) {
|
||||
return (
|
||||
<Icon
|
||||
as={FaEllipsisH}
|
||||
sx={{
|
||||
boxSize: iconBoxSize,
|
||||
color: 'base.300',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return <Icon as={FaEllipsisH} boxSize={iconBoxSize} color="base.300" />;
|
||||
}
|
||||
if (status === zNodeStatus.enum.IN_PROGRESS) {
|
||||
return progress === null ? (
|
||||
@ -153,26 +144,10 @@ const StatusIcon = memo((props: StatusIconProps) => {
|
||||
);
|
||||
}
|
||||
if (status === zNodeStatus.enum.COMPLETED) {
|
||||
return (
|
||||
<Icon
|
||||
as={FaCheck}
|
||||
sx={{
|
||||
boxSize: iconBoxSize,
|
||||
color: 'ok.300',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return <Icon as={FaCheck} boxSize={iconBoxSize} color="ok.300" />;
|
||||
}
|
||||
if (status === zNodeStatus.enum.FAILED) {
|
||||
return (
|
||||
<Icon
|
||||
as={FaExclamation}
|
||||
sx={{
|
||||
boxSize: iconBoxSize,
|
||||
color: 'error.300',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return <Icon as={FaExclamation} boxSize={iconBoxSize} color="error.300" />;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
@ -29,40 +29,29 @@ const InvocationNodeUnknownFallback = ({
|
||||
<Flex
|
||||
className={DRAG_HANDLE_CLASSNAME}
|
||||
layerStyle="nodeHeader"
|
||||
sx={{
|
||||
borderTopRadius: 'base',
|
||||
borderBottomRadius: isOpen ? 0 : 'base',
|
||||
alignItems: 'center',
|
||||
h: 8,
|
||||
fontWeight: 'semibold',
|
||||
fontSize: 'sm',
|
||||
}}
|
||||
borderTopRadius="base"
|
||||
borderBottomRadius={isOpen ? 0 : 'base'}
|
||||
alignItems="center"
|
||||
h={8}
|
||||
fontWeight="semibold"
|
||||
fontSize="sm"
|
||||
>
|
||||
<NodeCollapseButton nodeId={nodeId} isOpen={isOpen} />
|
||||
<InvText
|
||||
sx={{
|
||||
w: 'full',
|
||||
textAlign: 'center',
|
||||
pe: 8,
|
||||
color: 'error.300',
|
||||
}}
|
||||
>
|
||||
<InvText w="full" textAlign="center" pe={8} color="error.300">
|
||||
{label ? `${label} (${type})` : type}
|
||||
</InvText>
|
||||
</Flex>
|
||||
{isOpen && (
|
||||
<Flex
|
||||
layerStyle="nodeBody"
|
||||
sx={{
|
||||
userSelect: 'auto',
|
||||
flexDirection: 'column',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
p: 4,
|
||||
gap: 1,
|
||||
borderBottomRadius: 'base',
|
||||
fontSize: 'sm',
|
||||
}}
|
||||
userSelect="auto"
|
||||
flexDirection="column"
|
||||
w="full"
|
||||
h="full"
|
||||
p={4}
|
||||
gap={1}
|
||||
borderBottomRadius="base"
|
||||
fontSize="sm"
|
||||
>
|
||||
<Flex gap={2} flexDir="column">
|
||||
<InvText as="span">
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { SystemStyleObject } from '@chakra-ui/react';
|
||||
import {
|
||||
Editable,
|
||||
EditableInput,
|
||||
@ -78,51 +79,28 @@ const EditableFieldTitle = forwardRef((props: Props, ref) => {
|
||||
>
|
||||
<Flex
|
||||
ref={ref}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
gap: 1,
|
||||
h: 'full',
|
||||
}}
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
alignItems="center"
|
||||
justifyContent="flex-start"
|
||||
gap={1}
|
||||
h="full"
|
||||
>
|
||||
<Editable
|
||||
value={localTitle}
|
||||
onChange={handleChange}
|
||||
onSubmit={handleSubmit}
|
||||
as={Flex}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
h: 'full',
|
||||
}}
|
||||
position="relative"
|
||||
alignItems="center"
|
||||
h="full"
|
||||
>
|
||||
<EditablePreview
|
||||
sx={{
|
||||
p: 0,
|
||||
fontWeight: isMissingInput ? 'bold' : 'normal',
|
||||
textAlign: 'left',
|
||||
_hover: {
|
||||
fontWeight: 'semibold !important',
|
||||
},
|
||||
}}
|
||||
fontWeight={isMissingInput ? 'bold' : 'normal'}
|
||||
sx={editablePreviewStyles}
|
||||
noOfLines={1}
|
||||
/>
|
||||
<EditableInput
|
||||
className="nodrag"
|
||||
sx={{
|
||||
p: 0,
|
||||
w: 'full',
|
||||
fontWeight: 'semibold',
|
||||
color: 'base.100',
|
||||
_focusVisible: {
|
||||
p: 0,
|
||||
textAlign: 'left',
|
||||
boxShadow: 'none',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<EditableInput className="nodrag" sx={editableInputStyles} />
|
||||
<EditableControls />
|
||||
</Editable>
|
||||
</Flex>
|
||||
@ -130,6 +108,25 @@ const EditableFieldTitle = forwardRef((props: Props, ref) => {
|
||||
);
|
||||
});
|
||||
|
||||
const editableInputStyles: SystemStyleObject = {
|
||||
p: 0,
|
||||
w: 'full',
|
||||
fontWeight: 'semibold',
|
||||
color: 'base.100',
|
||||
_focusVisible: {
|
||||
p: 0,
|
||||
textAlign: 'left',
|
||||
boxShadow: 'none',
|
||||
},
|
||||
};
|
||||
const editablePreviewStyles: SystemStyleObject = {
|
||||
p: 0,
|
||||
textAlign: 'left',
|
||||
_hover: {
|
||||
fontWeight: 'semibold !important',
|
||||
},
|
||||
};
|
||||
|
||||
export default memo(EditableFieldTitle);
|
||||
|
||||
const EditableControls = memo(() => {
|
||||
|
@ -103,10 +103,7 @@ const FieldContextMenu = ({ nodeId, fieldName, kind, children }: Props) => {
|
||||
const renderMenuFunc = useCallback(
|
||||
() =>
|
||||
!menuItems.length ? null : (
|
||||
<InvMenuList
|
||||
sx={{ visibility: 'visible !important' }}
|
||||
onContextMenu={skipEvent}
|
||||
>
|
||||
<InvMenuList visibility="visible" onContextMenu={skipEvent}>
|
||||
<InvMenuGroup
|
||||
title={label || fieldTemplateTitle || t('nodes.unknownField')}
|
||||
>
|
||||
|
@ -19,17 +19,15 @@ const FieldTitle = forwardRef((props: Props, ref) => {
|
||||
return (
|
||||
<Flex
|
||||
ref={ref}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
gap: 1,
|
||||
h: 'full',
|
||||
w: 'full',
|
||||
}}
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
alignItems="center"
|
||||
justifyContent="flex-start"
|
||||
gap={1}
|
||||
h="full"
|
||||
w="full"
|
||||
>
|
||||
<InvText sx={{ fontWeight: isMissingInput ? 'bold' : 'normal' }}>
|
||||
<InvText fontWeight={isMissingInput ? 'bold' : 'normal'}>
|
||||
{label || fieldTemplateTitle}
|
||||
</InvText>
|
||||
</Flex>
|
||||
|
@ -43,10 +43,10 @@ const FieldTooltipContent = ({ nodeId, fieldName, kind }: Props) => {
|
||||
}, [field, fieldTemplate, t]);
|
||||
|
||||
return (
|
||||
<Flex sx={{ flexDir: 'column' }}>
|
||||
<InvText sx={{ fontWeight: 'semibold' }}>{fieldTitle}</InvText>
|
||||
<Flex flexDir="column">
|
||||
<InvText fontWeight="semibold">{fieldTitle}</InvText>
|
||||
{fieldTemplate && (
|
||||
<InvText sx={{ opacity: 0.7, fontStyle: 'oblique 5deg' }}>
|
||||
<InvText opacity={0.7} fontStyle="oblique 5deg">
|
||||
{fieldTemplate.description}
|
||||
</InvText>
|
||||
)}
|
||||
|
@ -292,13 +292,7 @@ const InputFieldRenderer = ({ nodeId, fieldName }: InputFieldProps) => {
|
||||
|
||||
return (
|
||||
<Box p={1}>
|
||||
<InvText
|
||||
sx={{
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'semibold',
|
||||
color: 'error.300',
|
||||
}}
|
||||
>
|
||||
<InvText fontSize="sm" fontWeight="semibold" color="error.300">
|
||||
{t('nodes.unknownFieldType', { type: fieldInstance?.type.name })}
|
||||
</InvText>
|
||||
</Box>
|
||||
|
@ -97,16 +97,14 @@ type OutputFieldWrapperProps = PropsWithChildren<{
|
||||
const OutputFieldWrapper = memo(
|
||||
({ shouldDim, children }: OutputFieldWrapperProps) => (
|
||||
<Flex
|
||||
sx={{
|
||||
position: 'relative',
|
||||
minH: 8,
|
||||
py: 0.5,
|
||||
alignItems: 'center',
|
||||
opacity: shouldDim ? 0.5 : 1,
|
||||
transitionProperty: 'opacity',
|
||||
transitionDuration: '0.1s',
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
position="relative"
|
||||
minH={8}
|
||||
py={0.5}
|
||||
alignItems="center"
|
||||
opacity={shouldDim ? 0.5 : 1}
|
||||
transitionProperty="opacity"
|
||||
transitionDuration="0.1s"
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
|
@ -56,7 +56,6 @@ const IPAdapterModelFieldInputComponent = (
|
||||
placeholder="Pick one"
|
||||
options={options}
|
||||
onChange={onChange}
|
||||
sx={{ width: '100%' }}
|
||||
/>
|
||||
</InvControl>
|
||||
</InvTooltip>
|
||||
|
@ -78,12 +78,10 @@ const ImageFieldInputComponent = (
|
||||
return (
|
||||
<Flex
|
||||
className="nodrag"
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
w="full"
|
||||
h="full"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<IAIDndImage
|
||||
imageDTO={imageDTO}
|
||||
|
@ -48,7 +48,7 @@ const MainModelFieldInputComponent = (props: Props) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex sx={{ w: 'full', alignItems: 'center', gap: 2 }}>
|
||||
<Flex w="full" alignItems="center" gap={2}>
|
||||
<InvControl
|
||||
className="nowheel nodrag"
|
||||
isDisabled={!options.length}
|
||||
|
@ -48,7 +48,7 @@ const RefinerModelFieldInputComponent = (props: Props) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex sx={{ w: 'full', alignItems: 'center', gap: 2 }}>
|
||||
<Flex w="full" alignItems="center" gap={2}>
|
||||
<InvControl
|
||||
className="nowheel nodrag"
|
||||
isDisabled={!options.length}
|
||||
|
@ -48,7 +48,7 @@ const SDXLMainModelFieldInputComponent = (props: Props) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex sx={{ w: 'full', alignItems: 'center', gap: 2 }}>
|
||||
<Flex w="full" alignItems="center" gap={2}>
|
||||
<InvControl
|
||||
className="nowheel nodrag"
|
||||
isDisabled={!options.length}
|
||||
|
@ -57,7 +57,6 @@ const T2IAdapterModelFieldInputComponent = (
|
||||
placeholder="Pick one"
|
||||
options={options}
|
||||
onChange={onChange}
|
||||
sx={{ width: '100%' }}
|
||||
/>
|
||||
</InvControl>
|
||||
</InvTooltip>
|
||||
|
@ -48,7 +48,7 @@ const VAEModelFieldInputComponent = (props: Props) => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex sx={{ w: 'full', alignItems: 'center', gap: 2 }}>
|
||||
<Flex w="full" alignItems="center" gap={2}>
|
||||
<InvControl
|
||||
className="nowheel nodrag"
|
||||
isDisabled={!options.length}
|
||||
|
@ -25,13 +25,11 @@ const NotesNode = (props: NodeProps<NotesNodeData>) => {
|
||||
<NodeWrapper nodeId={nodeId} selected={selected}>
|
||||
<Flex
|
||||
layerStyle="nodeHeader"
|
||||
sx={{
|
||||
borderTopRadius: 'base',
|
||||
borderBottomRadius: isOpen ? 0 : 'base',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
h: 8,
|
||||
}}
|
||||
borderTopRadius="base"
|
||||
borderBottomRadius={isOpen ? 0 : 'base'}
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
h={8}
|
||||
>
|
||||
<NodeCollapseButton nodeId={nodeId} isOpen={isOpen} />
|
||||
<NodeTitle nodeId={nodeId} title="Notes" />
|
||||
@ -42,26 +40,21 @@ const NotesNode = (props: NodeProps<NotesNodeData>) => {
|
||||
<Flex
|
||||
layerStyle="nodeBody"
|
||||
className="nopan"
|
||||
sx={{
|
||||
cursor: 'auto',
|
||||
flexDirection: 'column',
|
||||
borderBottomRadius: 'base',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
p: 2,
|
||||
gap: 1,
|
||||
}}
|
||||
cursor="auto"
|
||||
flexDirection="column"
|
||||
borderBottomRadius="base"
|
||||
w="full"
|
||||
h="full"
|
||||
p={2}
|
||||
gap={1}
|
||||
>
|
||||
<Flex
|
||||
className="nopan"
|
||||
sx={{ flexDir: 'column', w: 'full', h: 'full' }}
|
||||
>
|
||||
<Flex className="nopan" w="full" h="full" flexDir="column">
|
||||
<InvTextarea
|
||||
value={notes}
|
||||
onChange={handleChange}
|
||||
rows={8}
|
||||
resize="none"
|
||||
sx={{ fontSize: 'xs' }}
|
||||
fontSize="sm"
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
@ -24,23 +24,15 @@ const NodeCollapseButton = ({ nodeId, isOpen }: Props) => {
|
||||
className="nodrag"
|
||||
onClick={handleClick}
|
||||
aria-label="Minimize"
|
||||
sx={{
|
||||
minW: 8,
|
||||
w: 8,
|
||||
h: 8,
|
||||
color: 'base.500',
|
||||
_hover: {
|
||||
color: 'base.300',
|
||||
},
|
||||
}}
|
||||
minW={8}
|
||||
w={8}
|
||||
h={8}
|
||||
variant="link"
|
||||
icon={
|
||||
<ChevronUpIcon
|
||||
sx={{
|
||||
transform: isOpen ? 'rotate(0deg)' : 'rotate(180deg)',
|
||||
transitionProperty: 'common',
|
||||
transitionDuration: 'normal',
|
||||
}}
|
||||
transform={isOpen ? 'rotate(0deg)' : 'rotate(180deg)'}
|
||||
transitionProperty="common"
|
||||
transitionDuration="normal"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { SystemStyleObject } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
Editable,
|
||||
@ -50,46 +51,28 @@ const NodeTitle = ({ nodeId, title }: Props) => {
|
||||
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
overflow: 'hidden',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
cursor: 'text',
|
||||
}}
|
||||
overflow="hidden"
|
||||
w="full"
|
||||
h="full"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
cursor="text"
|
||||
>
|
||||
<Editable
|
||||
as={Flex}
|
||||
value={localTitle}
|
||||
onChange={handleChange}
|
||||
onSubmit={handleSubmit}
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
alignItems="center"
|
||||
position="relative"
|
||||
w="full"
|
||||
h="full"
|
||||
>
|
||||
<EditablePreview
|
||||
fontSize="sm"
|
||||
sx={{
|
||||
p: 0,
|
||||
w: 'full',
|
||||
}}
|
||||
noOfLines={1}
|
||||
/>
|
||||
<EditablePreview fontSize="sm" p={0} w="full" noOfLines={1} />
|
||||
<EditableInput
|
||||
className="nodrag"
|
||||
fontSize="sm"
|
||||
sx={{
|
||||
p: 0,
|
||||
fontWeight: 'bold',
|
||||
_focusVisible: {
|
||||
p: 0,
|
||||
boxShadow: 'none',
|
||||
},
|
||||
}}
|
||||
sx={editableInputStyles}
|
||||
/>
|
||||
<EditableControls />
|
||||
</Editable>
|
||||
@ -120,13 +103,19 @@ function EditableControls() {
|
||||
<Box
|
||||
className={DRAG_HANDLE_CLASSNAME}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
top: 0,
|
||||
cursor: 'grab',
|
||||
}}
|
||||
position="absolute"
|
||||
w="full"
|
||||
h="full"
|
||||
top={0}
|
||||
cursor="grab"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const editableInputStyles: SystemStyleObject = {
|
||||
p: 0,
|
||||
fontWeight: 'bold',
|
||||
_focusVisible: {
|
||||
p: 0,
|
||||
},
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ import { memo, useCallback, useMemo } from 'react';
|
||||
type NodeWrapperProps = PropsWithChildren & {
|
||||
nodeId: string;
|
||||
selected: boolean;
|
||||
width?: NonNullable<ChakraProps['sx']>['w'];
|
||||
width?: ChakraProps['w'];
|
||||
};
|
||||
|
||||
const NodeWrapper = (props: NodeWrapperProps) => {
|
||||
@ -65,45 +65,39 @@ const NodeWrapper = (props: NodeWrapperProps) => {
|
||||
onMouseEnter={handleMouseOver}
|
||||
onMouseLeave={handleMouseOut}
|
||||
className={DRAG_HANDLE_CLASSNAME}
|
||||
sx={{
|
||||
h: 'full',
|
||||
position: 'relative',
|
||||
borderRadius: 'base',
|
||||
w: width ?? NODE_WIDTH,
|
||||
transitionProperty: 'common',
|
||||
transitionDuration: '0.1s',
|
||||
cursor: 'grab',
|
||||
opacity,
|
||||
}}
|
||||
h="full"
|
||||
position="relative"
|
||||
borderRadius="base"
|
||||
w={width ? width : NODE_WIDTH}
|
||||
transitionProperty="common"
|
||||
transitionDuration="0.1s"
|
||||
cursor="grab"
|
||||
opacity={opacity}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
insetInlineEnd: 0,
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
borderRadius: 'base',
|
||||
pointerEvents: 'none',
|
||||
shadow: `${shadowsXl}, ${shadowsBase}, ${shadowsBase}`,
|
||||
zIndex: -1,
|
||||
}}
|
||||
position="absolute"
|
||||
top={0}
|
||||
insetInlineEnd={0}
|
||||
bottom={0}
|
||||
insetInlineStart={0}
|
||||
borderRadius="base"
|
||||
pointerEvents="none"
|
||||
shadow={`${shadowsXl}, ${shadowsBase}, ${shadowsBase}`}
|
||||
zIndex={-1}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
insetInlineEnd: 0,
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
borderRadius: 'md',
|
||||
pointerEvents: 'none',
|
||||
transitionProperty: 'common',
|
||||
transitionDuration: '0.1s',
|
||||
opacity: 0.7,
|
||||
shadow: isInProgress ? nodeInProgress : undefined,
|
||||
zIndex: -1,
|
||||
}}
|
||||
position="absolute"
|
||||
top={0}
|
||||
insetInlineEnd={0}
|
||||
bottom={0}
|
||||
insetInlineStart={0}
|
||||
borderRadius="md"
|
||||
pointerEvents="none"
|
||||
transitionProperty="common"
|
||||
transitionDuration="0.1s"
|
||||
opacity={0.7}
|
||||
shadow={isInProgress ? nodeInProgress : undefined}
|
||||
zIndex={-1}
|
||||
/>
|
||||
{children}
|
||||
<NodeSelectionOverlay isSelected={selected} isHovered={isMouseOverNode} />
|
||||
|
@ -5,7 +5,7 @@ import NodeOpacitySlider from './NodeOpacitySlider';
|
||||
import ViewportControls from './ViewportControls';
|
||||
|
||||
const BottomLeftPanel = () => (
|
||||
<Flex sx={{ gap: 2, position: 'absolute', bottom: 2, insetInlineStart: 2 }}>
|
||||
<Flex gap={2} position="absolute" bottom={2} insetInlineStart={2}>
|
||||
<ViewportControls />
|
||||
<NodeOpacitySlider />
|
||||
</Flex>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { SystemStyleObject } from '@chakra-ui/react';
|
||||
import { chakra, Flex } from '@chakra-ui/react';
|
||||
import type { RootState } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
@ -6,26 +7,28 @@ import { MiniMap } from 'reactflow';
|
||||
|
||||
const ChakraMiniMap = chakra(MiniMap);
|
||||
|
||||
const minimapStyles: SystemStyleObject = {
|
||||
m: '0 !important',
|
||||
borderRadius: 'base',
|
||||
backgroundColor: 'base.500 !important',
|
||||
svg: {
|
||||
borderRadius: 'inherit',
|
||||
},
|
||||
};
|
||||
|
||||
const MinimapPanel = () => {
|
||||
const shouldShowMinimapPanel = useAppSelector(
|
||||
(state: RootState) => state.nodes.shouldShowMinimapPanel
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex sx={{ gap: 2, position: 'absolute', bottom: 2, insetInlineEnd: 2 }}>
|
||||
<Flex gap={2} position="absolute" bottom={2} insetInlineEnd={2}>
|
||||
{shouldShowMinimapPanel && (
|
||||
<ChakraMiniMap
|
||||
pannable
|
||||
zoomable
|
||||
nodeBorderRadius={15}
|
||||
sx={{
|
||||
m: '0 !important',
|
||||
borderRadius: 'base',
|
||||
backgroundColor: 'base.500 !important',
|
||||
svg: {
|
||||
borderRadius: 'inherit',
|
||||
},
|
||||
}}
|
||||
sx={minimapStyles}
|
||||
nodeColor="var(--invokeai-colors-blue-600)"
|
||||
maskColor="var(--invokeai-colors-blackAlpha-600)"
|
||||
/>
|
||||
|
@ -13,15 +13,13 @@ const TopCenterPanel = () => {
|
||||
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
gap: 2,
|
||||
top: 2,
|
||||
left: 2,
|
||||
right: 2,
|
||||
position: 'absolute',
|
||||
alignItems: 'center',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
gap={2}
|
||||
top={2}
|
||||
left={2}
|
||||
right={2}
|
||||
position="absolute"
|
||||
alignItems="center"
|
||||
pointerEvents="none"
|
||||
>
|
||||
<AddNodeButton />
|
||||
<UpdateNodesButton />
|
||||
|
@ -9,7 +9,7 @@ const TopRightPanel = () => {
|
||||
useFeatureStatus('workflowLibrary').isFeatureEnabled;
|
||||
|
||||
return (
|
||||
<Flex sx={{ gap: 2, position: 'absolute', top: 2, insetInlineEnd: 2 }}>
|
||||
<Flex gap={2} position="absolute" top={2} insetInlineEnd={2}>
|
||||
{isWorkflowLibraryEnabled && <WorkflowLibraryButton />}
|
||||
<WorkflowLibraryMenu />
|
||||
</Flex>
|
||||
|
@ -104,13 +104,7 @@ const WorkflowEditorSettings = ({ children }: Props) => {
|
||||
<InvModalHeader>{t('nodes.workflowSettings')}</InvModalHeader>
|
||||
<InvModalCloseButton />
|
||||
<InvModalBody>
|
||||
<Flex
|
||||
sx={{
|
||||
flexDirection: 'column',
|
||||
gap: 4,
|
||||
py: 4,
|
||||
}}
|
||||
>
|
||||
<Flex flexDirection="column" gap={4} py={4}>
|
||||
<Heading size="sm">{t('parameters.general')}</Heading>
|
||||
<InvControl
|
||||
label={t('nodes.animatedEdges')}
|
||||
|
@ -24,7 +24,7 @@ const NodeEditorPanelGroup = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex sx={{ flexDir: 'column', gap: 2, height: '100%', width: '100%' }}>
|
||||
<Flex w="full" h="full" gap={2} flexDir="column">
|
||||
<QueueControls />
|
||||
<PanelGroup
|
||||
ref={panelGroupRef}
|
||||
|
@ -52,24 +52,16 @@ const InspectorOutputsTab = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'relative',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
<Box position="relative" w="full" h="full">
|
||||
<ScrollableContent>
|
||||
<Flex
|
||||
sx={{
|
||||
position: 'relative',
|
||||
flexDir: 'column',
|
||||
alignItems: 'flex-start',
|
||||
p: 1,
|
||||
gap: 2,
|
||||
h: 'full',
|
||||
w: 'full',
|
||||
}}
|
||||
position="relative"
|
||||
flexDir="column"
|
||||
alignItems="flex-start"
|
||||
p={1}
|
||||
gap={2}
|
||||
h="full"
|
||||
w="full"
|
||||
>
|
||||
{template?.outputType === 'image_output' ? (
|
||||
nes.outputs.map((result, i) => (
|
||||
|
@ -19,19 +19,14 @@ const InspectorPanel = () => {
|
||||
return (
|
||||
<Flex
|
||||
layerStyle="first"
|
||||
sx={{
|
||||
flexDir: 'column',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
borderRadius: 'base',
|
||||
p: 2,
|
||||
gap: 2,
|
||||
}}
|
||||
flexDir="column"
|
||||
w="full"
|
||||
h="full"
|
||||
borderRadius="base"
|
||||
p={2}
|
||||
gap={2}
|
||||
>
|
||||
<Tabs
|
||||
variant="line"
|
||||
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
|
||||
>
|
||||
<Tabs variant="line" display="flex" flexDir="column" w="full" h="full">
|
||||
<TabList>
|
||||
<Tab>{t('common.details')}</Tab>
|
||||
<Tab>{t('common.outputs')}</Tab>
|
||||
|
@ -87,16 +87,9 @@ const WorkflowGeneralTab = () => {
|
||||
|
||||
return (
|
||||
<ScrollableContent>
|
||||
<Flex
|
||||
sx={{
|
||||
flexDir: 'column',
|
||||
alignItems: 'flex-start',
|
||||
gap: 2,
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
<Flex flexDir="column" alignItems="flex-start" gap={2} h="full">
|
||||
<InvControlGroup orientation="vertical">
|
||||
<Flex sx={{ gap: 2, w: 'full' }}>
|
||||
<Flex gap={2} w="full">
|
||||
<InvControl label={t('nodes.workflowName')}>
|
||||
<InvInput value={name} onChange={handleChangeName} />
|
||||
</InvControl>
|
||||
@ -104,7 +97,7 @@ const WorkflowGeneralTab = () => {
|
||||
<InvInput value={version} onChange={handleChangeVersion} />
|
||||
</InvControl>
|
||||
</Flex>
|
||||
<Flex sx={{ gap: 2, w: 'full' }}>
|
||||
<Flex gap={2} w="full">
|
||||
<InvControl label={t('nodes.workflowAuthor')}>
|
||||
<InvInput value={author} onChange={handleChangeAuthor} />
|
||||
</InvControl>
|
||||
|
@ -9,14 +9,7 @@ const WorkflowJSONTab = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
flexDir: 'column',
|
||||
alignItems: 'flex-start',
|
||||
gap: 2,
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
<Flex flexDir="column" alignItems="flex-start" gap={2} h="full">
|
||||
<DataViewer data={workflow} label={t('nodes.workflow')} />
|
||||
</Flex>
|
||||
);
|
||||
|
@ -19,24 +19,16 @@ const WorkflowLinearTab = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'relative',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
<Box position="relative" w="full" h="full">
|
||||
<ScrollableContent>
|
||||
<Flex
|
||||
sx={{
|
||||
position: 'relative',
|
||||
flexDir: 'column',
|
||||
alignItems: 'flex-start',
|
||||
p: 1,
|
||||
gap: 2,
|
||||
h: 'full',
|
||||
w: 'full',
|
||||
}}
|
||||
position="relative"
|
||||
flexDir="column"
|
||||
alignItems="flex-start"
|
||||
p={1}
|
||||
gap={2}
|
||||
h="full"
|
||||
w="full"
|
||||
>
|
||||
{fields.length ? (
|
||||
fields.map(({ nodeId, fieldName }) => (
|
||||
|
@ -18,19 +18,14 @@ const WorkflowPanel = () => {
|
||||
return (
|
||||
<Flex
|
||||
layerStyle="first"
|
||||
sx={{
|
||||
flexDir: 'column',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
borderRadius: 'base',
|
||||
p: 2,
|
||||
gap: 2,
|
||||
}}
|
||||
flexDir="column"
|
||||
w="full"
|
||||
h="full"
|
||||
borderRadius="base"
|
||||
p={2}
|
||||
gap={2}
|
||||
>
|
||||
<Tabs
|
||||
variant="line"
|
||||
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
|
||||
>
|
||||
<Tabs variant="line" display="flex" w="full" h="full" flexDir="column">
|
||||
<TabList>
|
||||
<Tab>{t('common.linear')}</Tab>
|
||||
<Tab>{t('common.details')}</Tab>
|
||||
|
Reference in New Issue
Block a user