Skip to content

Commit 05de3b7

Browse files
Mary Hipppsychedelicious
authored andcommitted
workflow library UI updates: scrollbar to make obvious its overflowing, move deselecet all tags to be next to browse button
1 parent 9cc2232 commit 05de3b7

File tree

10 files changed

+71
-42
lines changed

10 files changed

+71
-42
lines changed

invokeai/frontend/web/src/common/components/OverlayScrollbars/constants.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,22 @@ export const overlayScrollbarsParams: UseOverlayScrollbarsParams = {
2020
},
2121
};
2222

23-
export const getOverlayScrollbarsParams = (
24-
overflowX: 'hidden' | 'scroll' = 'hidden',
25-
overflowY: 'hidden' | 'scroll' = 'scroll'
26-
) => {
23+
export const getOverlayScrollbarsParams = ({
24+
overflowX = 'hidden',
25+
overflowY = 'scroll',
26+
visibility = 'auto',
27+
}: {
28+
overflowX?: 'hidden' | 'scroll';
29+
overflowY?: 'hidden' | 'scroll';
30+
visibility?: 'auto' | 'hidden' | 'visible';
31+
}) => {
2732
const params = deepClone(overlayScrollbarsParams);
28-
merge(params, { options: { overflow: { y: overflowY, x: overflowX } } });
33+
merge(params, {
34+
options: {
35+
overflow: { y: overflowY, x: overflowX },
36+
scrollbars: { visibility, autoHide: visibility === 'visible' ? 'never' : 'scroll' },
37+
},
38+
});
2939
return params;
3040
};
3141

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/FloatFieldCollectionInputComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { PiXBold } from 'react-icons/pi';
2424

2525
import type { FieldComponentProps } from './types';
2626

27-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
27+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
2828

2929
const sx = {
3030
borderWidth: 1,

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/FloatGeneratorFieldComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { memo, useCallback, useMemo } from 'react';
2424
import { useTranslation } from 'react-i18next';
2525
import { useDebounce } from 'use-debounce';
2626

27-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
27+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
2828

2929
export const FloatGeneratorFieldInputComponent = memo(
3030
(props: FieldComponentProps<FloatGeneratorFieldInputInstance, FloatGeneratorFieldInputTemplate>) => {

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ImageFieldCollectionInputComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type { ImageDTO } from 'services/api/types';
2424

2525
import type { FieldComponentProps } from './types';
2626

27-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
27+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
2828

2929
const sx = {
3030
borderWidth: 1,

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ImageGeneratorFieldComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type { ChangeEvent } from 'react';
1717
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
1818
import { useTranslation } from 'react-i18next';
1919

20-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
20+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
2121

2222
export const ImageGeneratorFieldInputComponent = memo(
2323
(props: FieldComponentProps<ImageGeneratorFieldInputInstance, ImageGeneratorFieldInputTemplate>) => {

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/IntegerFieldCollectionInputComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { PiXBold } from 'react-icons/pi';
2727

2828
import type { FieldComponentProps } from './types';
2929

30-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
30+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
3131

3232
const sx = {
3333
borderWidth: 1,

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/IntegerGeneratorFieldComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { memo, useCallback, useMemo } from 'react';
2727
import { useTranslation } from 'react-i18next';
2828
import { useDebounce } from 'use-debounce';
2929

30-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
30+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
3131

3232
export const IntegerGeneratorFieldInputComponent = memo(
3333
(props: FieldComponentProps<IntegerGeneratorFieldInputInstance, IntegerGeneratorFieldInputTemplate>) => {

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/StringFieldCollectionInputComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { PiXBold } from 'react-icons/pi';
1717

1818
import type { FieldComponentProps } from './types';
1919

20-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
20+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
2121

2222
const sx = {
2323
borderWidth: 1,

invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/StringGeneratorFieldComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import type { ChangeEvent } from 'react';
2121
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
2222
import { useTranslation } from 'react-i18next';
2323

24-
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
24+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
2525

2626
export const StringGeneratorFieldInputComponent = memo(
2727
(props: FieldComponentProps<StringGeneratorFieldInputInstance, StringGeneratorFieldInputTemplate>) => {

invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowLibrary/WorkflowLibrarySideNav.tsx

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
import type { ButtonProps, CheckboxProps } from '@invoke-ai/ui-library';
2-
import { Button, Checkbox, Collapse, Flex, Spacer, Text } from '@invoke-ai/ui-library';
2+
import {
3+
Button,
4+
ButtonGroup,
5+
Checkbox,
6+
Collapse,
7+
Flex,
8+
IconButton,
9+
Spacer,
10+
Text,
11+
Tooltip,
12+
} from '@invoke-ai/ui-library';
313
import { useStore } from '@nanostores/react';
414
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
15+
import { getOverlayScrollbarsParams, overlayScrollbarsStyles } from 'common/components/OverlayScrollbars/constants';
516
import type { WorkflowLibraryView, WorkflowTagCategory } from 'features/nodes/store/workflowLibrarySlice';
617
import {
718
$workflowLibraryCategoriesOptions,
@@ -15,6 +26,7 @@ import {
1526
} from 'features/nodes/store/workflowLibrarySlice';
1627
import { NewWorkflowButton } from 'features/workflowLibrary/components/NewWorkflowButton';
1728
import { UploadWorkflowButton } from 'features/workflowLibrary/components/UploadWorkflowButton';
29+
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
1830
import { memo, useCallback, useMemo } from 'react';
1931
import { useTranslation } from 'react-i18next';
2032
import { PiArrowCounterClockwiseBold, PiUsersBold } from 'react-icons/pi';
@@ -25,9 +37,14 @@ export const WorkflowLibrarySideNav = () => {
2537
const { t } = useTranslation();
2638
const categoryOptions = useStore($workflowLibraryCategoriesOptions);
2739
const view = useAppSelector(selectWorkflowLibraryView);
40+
const dispatch = useAppDispatch();
41+
const selectedTags = useAppSelector(selectWorkflowLibrarySelectedTags);
42+
const resetTags = useCallback(() => {
43+
dispatch(workflowLibraryTagsReset());
44+
}, [dispatch]);
2845

2946
return (
30-
<Flex h="full" minH={0} overflow="hidden" flexDir="column" w={64} gap={1}>
47+
<Flex h="full" minH={0} overflow="hidden" flexDir="column" w={64} gap={0}>
3148
<Flex flexDir="column" w="full" pb={2}>
3249
<WorkflowLibraryViewButton view="recent">{t('workflows.recentlyOpened')}</WorkflowLibraryViewButton>
3350
</Flex>
@@ -48,7 +65,26 @@ export const WorkflowLibrarySideNav = () => {
4865
)}
4966
</Flex>
5067
<Flex h="full" minH={0} overflow="hidden" flexDir="column">
51-
<WorkflowLibraryViewButton view="defaults">{t('workflows.browseWorkflows')}</WorkflowLibraryViewButton>
68+
{view === 'defaults' && selectedTags.length > 0 ? (
69+
<ButtonGroup>
70+
<WorkflowLibraryViewButton view="defaults" w="auto">
71+
{t('workflows.browseWorkflows')}
72+
</WorkflowLibraryViewButton>
73+
<Tooltip label={t('workflows.deselectAll')}>
74+
<IconButton
75+
onClick={resetTags}
76+
size="md"
77+
aria-label={t('workflows.deselectAll')}
78+
icon={<PiArrowCounterClockwiseBold size={12} />}
79+
variant="ghost"
80+
bg="base.700"
81+
color="base.50"
82+
/>
83+
</Tooltip>
84+
</ButtonGroup>
85+
) : (
86+
<WorkflowLibraryViewButton view="defaults">{t('workflows.browseWorkflows')}</WorkflowLibraryViewButton>
87+
)}
5288
<DefaultsViewCheckboxesCollapsible />
5389
</Flex>
5490
<Spacer />
@@ -58,39 +94,22 @@ export const WorkflowLibrarySideNav = () => {
5894
);
5995
};
6096

97+
const overlayscrollbarsOptions = getOverlayScrollbarsParams({ visibility: 'visible' }).options;
98+
6199
const DefaultsViewCheckboxesCollapsible = memo(() => {
62-
const { t } = useTranslation();
63-
const dispatch = useDispatch();
64-
const tags = useAppSelector(selectWorkflowLibrarySelectedTags);
65100
const tagCategoryOptions = useStore($workflowLibraryTagCategoriesOptions);
66101
const view = useAppSelector(selectWorkflowLibraryView);
67102

68-
const resetTags = useCallback(() => {
69-
dispatch(workflowLibraryTagsReset());
70-
}, [dispatch]);
71-
72103
return (
73104
<Collapse in={view === 'defaults'}>
74105
<Flex flexDir="column" gap={2} pl={4} py={2} overflow="hidden" h="100%" minH={0}>
75-
<Button
76-
isDisabled={tags.length === 0}
77-
onClick={resetTags}
78-
size="sm"
79-
variant="link"
80-
fontWeight="bold"
81-
justifyContent="flex-start"
82-
flexGrow={0}
83-
flexShrink={0}
84-
leftIcon={<PiArrowCounterClockwiseBold />}
85-
h={8}
86-
>
87-
{t('workflows.deselectAll')}
88-
</Button>
89-
<Flex flexDir="column" gap={2} overflow="auto">
90-
{tagCategoryOptions.map((tagCategory) => (
91-
<TagCategory key={tagCategory.categoryTKey} tagCategory={tagCategory} />
92-
))}
93-
</Flex>
106+
<OverlayScrollbarsComponent style={overlayScrollbarsStyles} options={overlayscrollbarsOptions}>
107+
<Flex flexDir="column" gap={2} overflow="auto">
108+
{tagCategoryOptions.map((tagCategory) => (
109+
<TagCategory key={tagCategory.categoryTKey} tagCategory={tagCategory} />
110+
))}
111+
</Flex>
112+
</OverlayScrollbarsComponent>
94113
</Flex>
95114
</Collapse>
96115
);

0 commit comments

Comments
 (0)