Skip to content

Commit 60d8dfd

Browse files
feat(ui): wip model picker
1 parent 073a2e3 commit 60d8dfd

File tree

2 files changed

+41
-73
lines changed

2 files changed

+41
-73
lines changed

invokeai/frontend/web/src/common/components/Picker/Picker.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@ export type PickerProps<T extends object, U> = {
9494
option: T;
9595
} & BoxProps
9696
>;
97-
GroupComponent?: React.ComponentType<
98-
PropsWithChildren<{ group: Group<T, U>; activeOptionId: string | undefined } & BoxProps>
99-
>;
97+
GroupComponent?: React.ComponentType<PropsWithChildren<{ group: Group<T, U> } & BoxProps>>;
10098
};
10199

102100
type PickerContextState<T extends object, U> = {
@@ -110,9 +108,7 @@ type PickerContextState<T extends object, U> = {
110108
NoOptionsFallbackComponent: React.ComponentType;
111109
NoMatchesFallbackComponent: React.ComponentType;
112110
OptionComponent: React.ComponentType<{ option: T } & BoxProps>;
113-
GroupComponent: React.ComponentType<
114-
PropsWithChildren<{ group: Group<T, U>; activeOptionId: string | undefined } & BoxProps>
115-
>;
111+
GroupComponent: React.ComponentType<PropsWithChildren<{ group: Group<T, U> } & BoxProps>>;
116112
};
117113

118114
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
@@ -501,7 +497,7 @@ const PickerOptionGroup = typedMemo(
501497
const { getOptionId, GroupComponent, getIsDisabled } = usePickerContext<T, U>();
502498

503499
return (
504-
<GroupComponent group={group} activeOptionId={activeOptionId}>
500+
<GroupComponent group={group}>
505501
{group.options.map((item) => {
506502
const id = getOptionId(item);
507503
return (

invokeai/frontend/web/src/features/settingsAccordions/components/GenerationSettingsAccordion/GenerationSettingsAccordion.tsx

+38-66
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ import type { BoxProps, FormLabelProps, InputProps, SystemStyleObject } from '@i
22
import {
33
Box,
44
Button,
5-
Collapse,
65
Expander,
76
Flex,
87
FormControlGroup,
98
FormLabel,
10-
Icon,
119
IconButton,
1210
Input,
1311
Popover,
@@ -27,7 +25,6 @@ import { InformationalPopover } from 'common/components/InformationalPopover/Inf
2725
import type { Group, ImperativeModelPickerHandle } from 'common/components/Picker/Picker';
2826
import { getRegex, Picker } from 'common/components/Picker/Picker';
2927
import { useDisclosure } from 'common/hooks/useBoolean';
30-
import { useStateImperative } from 'common/hooks/useStateImperative';
3128
import { fixedForwardRef } from 'common/util/fixedForwardRef';
3229
import { typedMemo } from 'common/util/typedMemo';
3330
import { selectLoRAsSlice } from 'features/controlLayers/store/lorasSlice';
@@ -52,7 +49,7 @@ import { selectActiveTab, selectCompactModelPicker } from 'features/ui/store/uiS
5249
import { compactModelPickerToggled } from 'features/ui/store/uiSlice';
5350
import { filesize } from 'filesize';
5451
import type { PropsWithChildren } from 'react';
55-
import { memo, useCallback, useEffect, useMemo, useRef } from 'react';
52+
import { memo, useCallback, useMemo, useRef } from 'react';
5653
import { useTranslation } from 'react-i18next';
5754
import { PiArrowsInLineVerticalBold, PiArrowsOutLineVerticalBold, PiCaretDownBold } from 'react-icons/pi';
5855
import { useMainModels } from 'services/api/hooks/modelsByType';
@@ -274,28 +271,8 @@ const SearchBarComponent = typedMemo(
274271
);
275272
SearchBarComponent.displayName = 'SearchBarComponent';
276273

277-
const toggleButtonSx = {
278-
"&[data-expanded='true']": {
279-
transform: 'rotate(180deg)',
280-
},
281-
} satisfies SystemStyleObject;
282-
283274
const PickerGroupComponent = memo(
284-
({
285-
group,
286-
activeOptionId,
287-
children,
288-
}: PropsWithChildren<{ group: Group<AnyModelConfig, GroupData>; activeOptionId: string | undefined }>) => {
289-
const [isOpen, setIsOpen, getIsOpen] = useStateImperative(true);
290-
useEffect(() => {
291-
if (group.options.some((option) => option.key === activeOptionId) && !getIsOpen()) {
292-
setIsOpen(true);
293-
}
294-
}, [activeOptionId, getIsOpen, group.options, setIsOpen]);
295-
const toggle = useCallback(() => {
296-
setIsOpen((prev) => !prev);
297-
}, [setIsOpen]);
298-
275+
({ group, children }: PropsWithChildren<{ group: Group<AnyModelConfig, GroupData> }>) => {
299276
return (
300277
<Flex
301278
flexDir="column"
@@ -304,20 +281,19 @@ const PickerGroupComponent = memo(
304281
borderLeftWidth={4}
305282
ps={2}
306283
>
307-
<GroupHeader group={group} isOpen={isOpen} toggle={toggle} />
308-
<Collapse in={isOpen} animateOpacity>
309-
<Flex flexDir="column" gap={1} w="full" py={1}>
310-
{children}
311-
</Flex>
312-
</Collapse>
284+
<GroupHeader group={group} />
285+
<Flex flexDir="column" gap={1} w="full" py={1}>
286+
{children}
287+
</Flex>
313288
</Flex>
314289
);
315290
}
316291
);
317292
PickerGroupComponent.displayName = 'PickerGroupComponent';
318293

319294
const groupSx = {
320-
alignItems: 'center',
295+
flexDir: 'column',
296+
flex: 1,
321297
ps: 2,
322298
pe: 4,
323299
py: 1,
@@ -326,43 +302,30 @@ const groupSx = {
326302
top: 0,
327303
bg: 'base.800',
328304
minH: 8,
329-
borderRadius: 'base',
330-
_hover: { bg: 'base.750' },
331305
} satisfies SystemStyleObject;
332306

333-
const GroupHeader = memo(
334-
({
335-
group,
336-
isOpen,
337-
toggle,
338-
...rest
339-
}: { group: Group<AnyModelConfig, GroupData>; isOpen: boolean; toggle: () => void } & BoxProps) => {
340-
const { t } = useTranslation();
341-
const compactModelPicker = useAppSelector(selectCompactModelPicker);
307+
const GroupHeader = memo(({ group, ...rest }: { group: Group<AnyModelConfig, GroupData> } & BoxProps) => {
308+
const { t } = useTranslation();
309+
const compactModelPicker = useAppSelector(selectCompactModelPicker);
342310

343-
return (
344-
<Flex {...rest} role="button" sx={groupSx} onClick={toggle}>
345-
<Flex flexDir="column" flex={1}>
346-
<Flex gap={2} alignItems="center">
347-
<Text fontSize="sm" fontWeight="semibold" color={`${BASE_COLOR_MAP[group.data.base]}.300`}>
348-
{MODEL_TYPE_SHORT_MAP[group.data.base]}
349-
</Text>
350-
<Text fontSize="sm" color="base.300" noOfLines={1}>
351-
{t('common.model_withCount', { count: group.options.length })}
352-
</Text>
353-
</Flex>
354-
{!compactModelPicker && (
355-
<Text color="base.200" fontStyle="italic">
356-
{group.data.description}
357-
</Text>
358-
)}
359-
<Spacer />
360-
</Flex>
361-
<Icon color="base.300" as={PiCaretDownBold} sx={toggleButtonSx} data-expanded={isOpen} boxSize={4} />
311+
return (
312+
<Flex {...rest} sx={groupSx}>
313+
<Flex gap={2} alignItems="center">
314+
<Text fontSize="sm" fontWeight="semibold" color={`${BASE_COLOR_MAP[group.data.base]}.300`}>
315+
{MODEL_TYPE_SHORT_MAP[group.data.base]}
316+
</Text>
317+
<Text fontSize="sm" color="base.300" noOfLines={1}>
318+
{t('common.model_withCount', { count: group.options.length })}
319+
</Text>
362320
</Flex>
363-
);
364-
}
365-
);
321+
{!compactModelPicker && (
322+
<Text color="base.200" fontStyle="italic">
323+
{group.data.description}
324+
</Text>
325+
)}
326+
</Flex>
327+
);
328+
});
366329
GroupHeader.displayName = 'GroupHeader';
367330

368331
const optionSx: SystemStyleObject = {
@@ -389,6 +352,15 @@ const optionSx: SystemStyleObject = {
389352
scrollMarginTop: '42px', // magic number, this is the height of the header
390353
};
391354

355+
const optionNameSx: SystemStyleObject = {
356+
fontSize: 'sm',
357+
noOfLines: 1,
358+
fontWeight: 'semibold',
359+
'&[data-is-compact="true"]': {
360+
fontWeight: 'normal',
361+
},
362+
};
363+
392364
export const PickerOptionComponent = typedMemo(({ option, ...rest }: { option: AnyModelConfig } & BoxProps) => {
393365
const compactModelPicker = useAppSelector(selectCompactModelPicker);
394366

@@ -397,7 +369,7 @@ export const PickerOptionComponent = typedMemo(({ option, ...rest }: { option: A
397369
{!compactModelPicker && <ModelImage image_url={option.cover_image} />}
398370
<Flex flexDir="column" gap={2} flex={1}>
399371
<Flex gap={2} alignItems="center">
400-
<Text fontSize="sm" fontWeight="semibold" noOfLines={1}>
372+
<Text sx={optionNameSx} data-is-compact={compactModelPicker}>
401373
{option.name}
402374
</Text>
403375
<Spacer />

0 commit comments

Comments
 (0)