feat(ui): iterate on model combobox (wip)

This commit is contained in:
psychedelicious
2025-04-15 14:06:38 +10:00
parent c52584e057
commit 677e717cd7
3 changed files with 13 additions and 84 deletions

View File

@@ -13,6 +13,7 @@ import {
useDisclosure,
} from '@invoke-ai/ui-library';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import { useStateImperative } from 'common/hooks/useStateImperative';
import ModelBaseBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelBaseBadge';
import ModelImage from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelImage';
@@ -82,7 +83,6 @@ const onSelect = (modelConfig: AnyModelConfig) => {
};
export const ModelCombobox = memo(() => {
const inputRef = useRef<HTMLInputElement>(null);
const pickerRef = useRef<ImperativeModelPickerHandle>(null);
const { isOpen, onOpen, onClose } = useDisclosure();
const [modelConfigs] = useAllModels();
@@ -92,7 +92,14 @@ export const ModelCombobox = memo(() => {
<Button onClick={onOpen} variant="outline">
model
</Button>
<Modal isOpen={isOpen} onClose={onClose} useInert={false} initialFocusRef={inputRef} size="xl" isCentered>
<Modal
isOpen={isOpen}
onClose={onClose}
useInert={false}
initialFocusRef={pickerRef.current?.inputRef}
size="xl"
isCentered
>
<ModalOverlay />
<ModalContent h="512" maxH="70%">
<ModalBody p={0}>
@@ -254,9 +261,9 @@ const ModelComboboxContent = memo(
<Flex tabIndex={-1} ref={rootRef} flexDir="column" p={2} h="full" gap={2} onKeyDown={onKeyDown}>
<Input ref={inputRef} value={searchTerm} onChange={onChangeSearchTerm} placeholder={t('nodes.nodeSearch')} />
<Box tabIndex={-1} role="listbox" w="full" h="full">
{/* <ScrollableContent> */}
<ModelComboboxList items={items} value={value} setValue={setValue} onSelect={onSelect} />
{/* </ScrollableContent> */}
<ScrollableContent>
<ModelComboboxList items={items} value={value} setValue={setValue} onSelect={onSelect} />
</ScrollableContent>
</Box>
</Flex>
);

View File

@@ -1,78 +0,0 @@
import type { SystemStyleObject } from '@invoke-ai/ui-library';
import { Box, Flex, Spacer, Text } from '@invoke-ai/ui-library';
import ModelBaseBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelBaseBadge';
import ModelImage from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelImage';
import { filesize } from 'filesize';
import { memo, useCallback } from 'react';
import type { AnyModelConfig } from 'services/api/types';
const itemSx: SystemStyleObject = {
display: 'flex',
flexDir: 'column',
p: 2,
cursor: 'pointer',
borderRadius: 'base',
'&[data-selected="true"]': {
bg: 'base.700',
},
'&[data-disabled="true"]': {
cursor: 'not-allowed',
opacity: 0.5,
},
};
export const ModelComboboxItem = memo(
(props: {
model: AnyModelConfig;
setActive: (key: string) => void;
onSelect: (key: string) => void;
isSelected: boolean;
isDisabled: boolean;
}) => {
const { model, setActive, onSelect, isDisabled, isSelected } = props;
const onPointerMove = useCallback(() => {
setActive(model.key);
}, [model.key, setActive]);
const onClick = useCallback(() => {
onSelect(model.key);
}, [model.key, onSelect]);
return (
<Box
role="option"
sx={itemSx}
id={model.key}
aria-disabled={isDisabled}
aria-selected={isSelected}
data-disabled={isDisabled}
data-selected={isSelected}
onPointerMove={isDisabled ? undefined : onPointerMove}
onClick={isDisabled ? undefined : onClick}
>
<ModelComboboxItemContent model={model} />
</Box>
);
}
);
ModelComboboxItem.displayName = 'ModelComboboxItem';
const ModelComboboxItemContent = memo(({ model }: { model: AnyModelConfig }) => {
return (
<Flex tabIndex={-1} gap={2}>
<ModelImage image_url={model.cover_image} />
<Flex flexDir="column" gap={2} flex={1}>
<Flex gap={2} alignItems="center">
<Text fontSize="sm" fontWeight="semibold">
{model.name}
</Text>
<Spacer />
<Text variant="subtext" fontStyle="italic">
{filesize(model.file_size)}
</Text>
<ModelBaseBadge base={model.base} />
</Flex>
{model.description && <Text color="base.200">{model.description}</Text>}
</Flex>
</Flex>
);
});
ModelComboboxItemContent.displayName = 'ModelComboboxItemContent';

View File

@@ -46,7 +46,7 @@ const ScrollableContent = ({ children, maxHeight, overflowX = 'hidden', overflow
return (
<Flex w="full" h="full" maxHeight={maxHeight} position="relative">
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
<OverlayScrollbarsComponent ref={os} style={styles} options={overlayscrollbarsOptions}>
<OverlayScrollbarsComponent ref={os} style={styles} options={overlayscrollbarsOptions} defer>
{children}
</OverlayScrollbarsComponent>
</Box>