mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-08 09:34:56 -05:00
feat(ui): iterate on builder (WIP)
This commit is contained in:
@@ -1,42 +1,31 @@
|
||||
import { Flex, type SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import { ContainerContext } from 'features/nodes/components/sidePanel/builder/ContainerContext';
|
||||
import {
|
||||
DIVIDER_CLASS_NAME,
|
||||
DividerElementComponent,
|
||||
} from 'features/nodes/components/sidePanel/builder/DividerElementComponent';
|
||||
import { DividerElementComponent } from 'features/nodes/components/sidePanel/builder/DividerElementComponent';
|
||||
import { HeadingElementComponent } from 'features/nodes/components/sidePanel/builder/HeadingElementComponent';
|
||||
import { NodeFieldElementComponent } from 'features/nodes/components/sidePanel/builder/NodeFieldElementComponent';
|
||||
import { TextElementComponent } from 'features/nodes/components/sidePanel/builder/TextElementComponent';
|
||||
import { useElement } from 'features/nodes/types/workflow';
|
||||
import { CONTAINER_CLASS_NAME, DIVIDER_CLASS_NAME, useElement } from 'features/nodes/types/workflow';
|
||||
import { memo } from 'react';
|
||||
import type { Equals } from 'tsafe';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
const CONTAINER_CLASS_NAME = getPrefixedId('container');
|
||||
|
||||
const sx: SystemStyleObject = {
|
||||
gap: 4,
|
||||
'&[data-container-direction="column"]': {
|
||||
flexDir: 'column',
|
||||
flex: '1 1 0',
|
||||
// Select all non-divider children (dividers have a fixed width that they define on their own)
|
||||
[`> *:not(.${DIVIDER_CLASS_NAME})`]: {
|
||||
// By default, all children should take up the same amount of space
|
||||
flex: '0 1 0',
|
||||
// The last child should take up the remaining space
|
||||
'&:last-child': {
|
||||
flex: '1 1 auto',
|
||||
},
|
||||
'> :last-child': {
|
||||
flex: '1 0 0',
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
},
|
||||
'&[data-container-direction="row"]': {
|
||||
// Select all non-divider children (dividers have a fixed width that they define on their own)
|
||||
[`> *:not(.${DIVIDER_CLASS_NAME})`]: {
|
||||
// By default, all children should take up the same amount of space
|
||||
'> *': {
|
||||
flex: '1 1 0',
|
||||
},
|
||||
},
|
||||
[`& > .${DIVIDER_CLASS_NAME}`]: {
|
||||
flex: '0 0 1px',
|
||||
},
|
||||
};
|
||||
|
||||
export const ContainerElementComponent = memo(({ id }: { id: string }) => {
|
||||
@@ -59,34 +48,6 @@ export const ContainerElementComponent = memo(({ id }: { id: string }) => {
|
||||
);
|
||||
});
|
||||
ContainerElementComponent.displayName = 'ContainerElementComponent';
|
||||
// export const ContainerElementComponent = memo(({ id }: { id: string }) => {
|
||||
// const element = useElement(id);
|
||||
|
||||
// if (!element || element.type !== 'container') {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// const { children, direction } = element.data;
|
||||
|
||||
// return (
|
||||
// <GridItem
|
||||
// as={Grid}
|
||||
// id={id}
|
||||
// gap={4}
|
||||
// w="full"
|
||||
// h="full"
|
||||
// gridTemplateColumns={direction === 'row' ? fill(children.length, '1fr') : undefined}
|
||||
// gridTemplateRows={direction === 'column' ? fill(children.length, 'min-content', '1fr') : undefined}
|
||||
// gridAutoFlow={direction === 'column' ? 'row' : 'column'}
|
||||
// alignItems="baseline"
|
||||
// >
|
||||
// {children.map((childId) => (
|
||||
// <FormElementComponent key={childId} id={childId} />
|
||||
// ))}
|
||||
// </GridItem>
|
||||
// );
|
||||
// });
|
||||
// ContainerElementComponent.displayName = 'ContainerElementComponent';
|
||||
|
||||
export const FormElementComponent = memo(({ id }: { id: string }) => {
|
||||
const element = useElement(id);
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import { DIVIDER_CLASS_NAME } from 'features/nodes/types/workflow';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const DIVIDER_CLASS_NAME = getPrefixedId('divider');
|
||||
|
||||
const sx: SystemStyleObject = {
|
||||
flex: '0 0 1px',
|
||||
bg: 'base.700',
|
||||
flexShrink: 0,
|
||||
};
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import type { FlexProps, SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { useContainerContext } from 'features/nodes/components/sidePanel/builder/ContainerContext';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { memo } from 'react';
|
||||
|
||||
const sx: SystemStyleObject = {
|
||||
// '&[data-container-direction="column"]': {
|
||||
// flex: '1 1 auto',
|
||||
// },
|
||||
// '&[data-container-direction="column"] > :not(:last-child)': {
|
||||
// bg: 'red',
|
||||
// },
|
||||
};
|
||||
|
||||
export const ElementWrapper = memo((props: PropsWithChildren<FlexProps>) => {
|
||||
const container = useContainerContext();
|
||||
return (
|
||||
<Flex
|
||||
sx={sx}
|
||||
// data-container-direction={container?.direction}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
ElementWrapper.displayName = 'ElementWrapper';
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Heading } from '@invoke-ai/ui-library';
|
||||
import { useElement } from 'features/nodes/types/workflow';
|
||||
import { HEADING_CLASS_NAME, useElement } from 'features/nodes/types/workflow';
|
||||
import { memo } from 'react';
|
||||
|
||||
const LEVEL_TO_SIZE = {
|
||||
@@ -16,11 +16,11 @@ export const HeadingElementComponent = memo(({ id }: { id: string }) => {
|
||||
if (!element || element.type !== 'heading') {
|
||||
return null;
|
||||
}
|
||||
const { data } = element;
|
||||
const { content, level } = data;
|
||||
|
||||
const { content, level } = element.data;
|
||||
|
||||
return (
|
||||
<Flex id={id}>
|
||||
<Flex id={id} className={HEADING_CLASS_NAME}>
|
||||
<Heading size={LEVEL_TO_SIZE[level]}>{content}</Heading>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { InputFieldGate } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldGate';
|
||||
import { InputFieldViewMode } from 'features/nodes/components/flow/nodes/Invocation/fields/InputFieldViewMode';
|
||||
import { useElement } from 'features/nodes/types/workflow';
|
||||
import { NODE_FIELD_CLASS_NAME, useElement } from 'features/nodes/types/workflow';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const NodeFieldElementComponent = memo(({ id }: { id: string }) => {
|
||||
@@ -14,7 +14,7 @@ export const NodeFieldElementComponent = memo(({ id }: { id: string }) => {
|
||||
const { fieldIdentifier } = data;
|
||||
|
||||
return (
|
||||
<Flex id={id}>
|
||||
<Flex id={id} className={NODE_FIELD_CLASS_NAME}>
|
||||
<InputFieldGate nodeId={fieldIdentifier.nodeId} fieldName={fieldIdentifier.fieldName}>
|
||||
<InputFieldViewMode nodeId={fieldIdentifier.nodeId} fieldName={fieldIdentifier.fieldName} />
|
||||
</InputFieldGate>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Text } from '@invoke-ai/ui-library';
|
||||
import { useElement } from 'features/nodes/types/workflow';
|
||||
import { TEXT_CLASS_NAME, useElement } from 'features/nodes/types/workflow';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const TextElementComponent = memo(({ id }: { id: string }) => {
|
||||
@@ -12,7 +12,7 @@ export const TextElementComponent = memo(({ id }: { id: string }) => {
|
||||
const { content, fontSize } = data;
|
||||
|
||||
return (
|
||||
<Flex id={id}>
|
||||
<Flex id={id} className={TEXT_CLASS_NAME}>
|
||||
<Text fontSize={fontSize}>{content}</Text>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -7,8 +7,8 @@ import { memo } from 'react';
|
||||
export const WorkflowBuilder = memo(() => {
|
||||
return (
|
||||
<ScrollableContent>
|
||||
<Flex w="full" h="full" justifyContent="center">
|
||||
<Flex w="full" h="full" maxW={512}>
|
||||
<Flex w="full" justifyContent="center">
|
||||
<Flex w="full" maxW={512}>
|
||||
<FormElementComponent id={rootId} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -113,6 +113,7 @@ const zElementBase = z.object({
|
||||
});
|
||||
|
||||
const NODE_FIELD_TYPE = 'node-field';
|
||||
export const NODE_FIELD_CLASS_NAME = getPrefixedId(NODE_FIELD_TYPE, '-');
|
||||
const zNodeFieldElement = zElementBase.extend({
|
||||
type: z.literal(NODE_FIELD_TYPE),
|
||||
data: z.object({
|
||||
@@ -136,6 +137,7 @@ const nodeField = (
|
||||
};
|
||||
|
||||
const HEADING_TYPE = 'heading';
|
||||
export const HEADING_CLASS_NAME = getPrefixedId(HEADING_TYPE, '-');
|
||||
const zHeadingElement = zElementBase.extend({
|
||||
type: z.literal(HEADING_TYPE),
|
||||
data: z.object({
|
||||
@@ -161,6 +163,7 @@ const heading = (
|
||||
};
|
||||
|
||||
const TEXT_TYPE = 'text';
|
||||
export const TEXT_CLASS_NAME = getPrefixedId(TEXT_TYPE, '-');
|
||||
const zTextElement = zElementBase.extend({
|
||||
type: z.literal(TEXT_TYPE),
|
||||
data: z.object({
|
||||
@@ -183,6 +186,7 @@ const text = (content: TextElement['data']['content'], fontSize: TextElement['da
|
||||
};
|
||||
|
||||
const DIVIDER_TYPE = 'divider';
|
||||
export const DIVIDER_CLASS_NAME = getPrefixedId(DIVIDER_TYPE, '-');
|
||||
const zDividerElement = zElementBase.extend({
|
||||
type: z.literal(DIVIDER_TYPE),
|
||||
});
|
||||
@@ -206,6 +210,7 @@ export type ContainerElement = {
|
||||
};
|
||||
|
||||
const CONTAINER_TYPE = 'container';
|
||||
export const CONTAINER_CLASS_NAME = getPrefixedId(CONTAINER_TYPE, '-');
|
||||
const zContainerElement: z.ZodType<ContainerElement> = zElementBase.extend({
|
||||
type: z.literal(CONTAINER_TYPE),
|
||||
data: z.object({
|
||||
@@ -239,6 +244,7 @@ export const rootId: string = container('column', [
|
||||
divider().id,
|
||||
heading('First Section', 2).id,
|
||||
text('The first section includes fields relevant to the first section. This note describes that fact.', 'sm').id,
|
||||
divider().id,
|
||||
container('row', [
|
||||
nodeField('7aed1a5f-7fd7-4184-abe8-ddea0ea5e706', 'image').id,
|
||||
divider().id,
|
||||
|
||||
Reference in New Issue
Block a user