cleanup: Remove IAICustomSelect and port types

This commit is contained in:
blessedcoolant 2023-06-13 01:30:53 +12:00 committed by psychedelicious
parent 9df502fc77
commit d282810e53
5 changed files with 44 additions and 283 deletions

View File

@ -1,256 +0,0 @@
import { CheckIcon, ChevronUpIcon } from '@chakra-ui/icons';
import {
Box,
Flex,
FormControl,
FormControlProps,
FormLabel,
Grid,
GridItem,
List,
ListItem,
Text,
Tooltip,
TooltipProps,
} from '@chakra-ui/react';
import { autoUpdate, offset, shift, useFloating } from '@floating-ui/react-dom';
import { useSelect } from 'downshift';
import { isString } from 'lodash-es';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import { memo, useLayoutEffect, useMemo } from 'react';
import { getInputOutlineStyles } from 'theme/util/getInputOutlineStyles';
export type ItemTooltips = { [key: string]: string };
export type IAICustomSelectOption = {
value: string;
label: string;
tooltip?: string;
};
type IAICustomSelectProps = {
label?: string;
value: string;
data: IAICustomSelectOption[] | string[];
onChange: (v: string) => void;
withCheckIcon?: boolean;
formControlProps?: FormControlProps;
tooltip?: string;
tooltipProps?: Omit<TooltipProps, 'children'>;
ellipsisPosition?: 'start' | 'end';
isDisabled?: boolean;
};
const IAICustomSelect = (props: IAICustomSelectProps) => {
const {
label,
withCheckIcon,
formControlProps,
tooltip,
tooltipProps,
ellipsisPosition = 'end',
data,
value,
onChange,
isDisabled = false,
} = props;
const values = useMemo(() => {
return data.map<IAICustomSelectOption>((v) => {
if (isString(v)) {
return { value: v, label: v };
}
return v;
});
}, [data]);
const stringValues = useMemo(() => {
return values.map((v) => v.value);
}, [values]);
const valueData = useMemo(() => {
return values.find((v) => v.value === value);
}, [values, value]);
const {
isOpen,
getToggleButtonProps,
getLabelProps,
getMenuProps,
highlightedIndex,
getItemProps,
} = useSelect({
items: stringValues,
selectedItem: value,
onSelectedItemChange: ({ selectedItem: newSelectedItem }) => {
newSelectedItem && onChange(newSelectedItem);
},
});
const { refs, floatingStyles, update } = useFloating<HTMLButtonElement>({
// whileElementsMounted: autoUpdate,
middleware: [offset(4), shift({ crossAxis: true, padding: 8 })],
});
useLayoutEffect(() => {
if (isOpen && refs.reference.current && refs.floating.current) {
return autoUpdate(refs.reference.current, refs.floating.current, update);
}
}, [isOpen, update, refs.floating, refs.reference]);
const labelTextDirection = useMemo(() => {
if (ellipsisPosition === 'start') {
return document.dir === 'rtl' ? 'ltr' : 'rtl';
}
return document.dir;
}, [ellipsisPosition]);
return (
<FormControl sx={{ w: 'full' }} {...formControlProps}>
{label && (
<FormLabel
{...getLabelProps()}
onClick={() => {
refs.floating.current && refs.floating.current.focus();
}}
>
{label}
</FormLabel>
)}
<Tooltip label={tooltip} {...tooltipProps}>
<Flex
{...getToggleButtonProps({ ref: refs.reference })}
sx={{
alignItems: 'center',
userSelect: 'none',
cursor: 'pointer',
overflow: 'hidden',
width: 'full',
py: 1,
px: 2,
gap: 2,
justifyContent: 'space-between',
pointerEvents: isDisabled ? 'none' : undefined,
opacity: isDisabled ? 0.5 : undefined,
...getInputOutlineStyles(),
}}
>
<Text
sx={{
fontSize: 'sm',
fontWeight: 500,
color: 'base.100',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
direction: labelTextDirection,
}}
>
{valueData?.label}
</Text>
<ChevronUpIcon
sx={{
color: 'base.300',
transform: isOpen ? 'rotate(0deg)' : 'rotate(180deg)',
transitionProperty: 'common',
transitionDuration: 'normal',
}}
/>
</Flex>
</Tooltip>
<Box {...getMenuProps()}>
{isOpen && (
<List
as={Flex}
ref={refs.floating}
sx={{
...floatingStyles,
top: 0,
insetInlineStart: 0,
flexDirection: 'column',
zIndex: 2,
bg: 'base.800',
borderRadius: 'base',
border: '1px',
borderColor: 'base.700',
shadow: 'dark-lg',
py: 2,
px: 0,
h: 'fit-content',
maxH: 64,
minW: 48,
}}
>
<OverlayScrollbarsComponent>
{values.map((v, index) => {
const isSelected = value === v.value;
const isHighlighted = highlightedIndex === index;
const fontWeight = isSelected ? 700 : 500;
const bg = isHighlighted
? 'base.700'
: isSelected
? 'base.750'
: undefined;
return (
<Tooltip
isDisabled={!v.tooltip}
key={`${v.value}${index}`}
label={v.tooltip}
hasArrow
placement="right"
>
<ListItem
sx={{
bg,
py: 1,
paddingInlineStart: 3,
paddingInlineEnd: 6,
cursor: 'pointer',
transitionProperty: 'common',
transitionDuration: '0.15s',
}}
{...getItemProps({ item: v.value, index })}
>
{withCheckIcon ? (
<Grid gridTemplateColumns="1.25rem auto">
<GridItem>
{isSelected && <CheckIcon boxSize={2} />}
</GridItem>
<GridItem>
<Text
sx={{
fontSize: 'sm',
color: 'base.100',
fontWeight,
}}
>
{v.label}
</Text>
</GridItem>
</Grid>
) : (
<Text
sx={{
fontSize: 'sm',
color: 'base.50',
fontWeight,
}}
>
{v.label}
</Text>
)}
</ListItem>
</Tooltip>
);
})}
</OverlayScrollbarsComponent>
</List>
)}
</Box>
</FormControl>
);
};
export default memo(IAICustomSelect);

View File

@ -2,6 +2,12 @@ import { Tooltip } from '@chakra-ui/react';
import { Select, SelectProps } from '@mantine/core';
import { memo } from 'react';
export type IAISelectDataType = {
value: string;
label: string;
tooltip?: string;
};
type IAISelectProps = SelectProps & {
tooltip?: string;
};

View File

@ -3,9 +3,9 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAICustomSelect, {
IAICustomSelectOption,
} from 'common/components/IAICustomSelect';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
import IAISelect from 'common/components/IAISelect';
import { useIsReadyToInvoke } from 'common/hooks/useIsReadyToInvoke';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
import {
CONTROLNET_MODELS,
ControlNetModelName,
@ -22,7 +22,7 @@ type ParamControlNetModelProps = {
const selector = createSelector(configSelector, (config) => {
return map(CONTROLNET_MODELS, (m) => ({
key: m.label,
label: m.label,
value: m.type,
})).filter((d) => !config.sd.disabledControlNetModels.includes(d.value));
});
@ -50,7 +50,7 @@ const ParamControlNetModel = (props: ParamControlNetModelProps) => {
return (
<IAIMantineSelect
data={DATA}
data={controlNetModels}
value={model}
onChange={handleModelChanged}
disabled={!isReady}

View File

@ -1,6 +1,8 @@
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { IAICustomSelectOption } from 'common/components/IAICustomSelect';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
import IAIMantineSelect, {
IAISelectDataType,
} from 'common/components/IAIMantineSelect';
import { map } from 'lodash-es';
import { ChangeEvent, memo, useCallback } from 'react';
import { CONTROLNET_PROCESSORS } from '../../store/constants';
@ -18,12 +20,20 @@ type ParamControlNetProcessorSelectProps = {
processorNode: ControlNetProcessorNode;
};
const CONTROLNET_PROCESSOR_TYPES = map(CONTROLNET_PROCESSORS, (p) => ({
value: p.type,
key: p.label,
})).sort((a, b) =>
const CONTROLNET_PROCESSOR_TYPES: IAISelectDataType[] = map(
CONTROLNET_PROCESSORS,
(p) => ({
value: p.type,
label: p.label,
tooltip: p.description,
})
).sort((a, b) =>
// sort 'none' to the top
a.value === 'none' ? -1 : b.value === 'none' ? 1 : a.key.localeCompare(b.key)
a.value === 'none'
? -1
: b.value === 'none'
? 1
: a.label.localeCompare(b.label)
);
const selector = createSelector(configSelector, (config) => {

View File

@ -1,12 +1,13 @@
import { createSelector } from '@reduxjs/toolkit';
import { isEqual } from 'lodash-es';
import { ChangeEvent, memo, useCallback } from 'react';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { IAICustomSelectOption } from 'common/components/IAICustomSelect';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
import IAIMantineSelect, {
IAISelectDataType,
} from 'common/components/IAIMantineSelect';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { modelSelected } from 'features/parameters/store/generationSlice';
import { selectModelsAll, selectModelsById } from '../store/modelSlice';
@ -17,11 +18,11 @@ const selector = createSelector(
const selectedModel = selectModelsById(state, generation.model);
const modelData = selectModelsAll(state)
.map((m) => ({
.map<IAISelectDataType>((m) => ({
value: m.name,
key: m.name,
label: m.name,
}))
.sort((a, b) => a.key.localeCompare(b.key));
.sort((a, b) => a.label.localeCompare(b.label));
// const modelData = selectModelsAll(state)
// .map<IAICustomSelectOption>((m) => ({
// value: m.name,
@ -45,21 +46,21 @@ const ModelSelect = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const { selectedModel, modelData } = useAppSelector(selector);
const handleChangeModel = useCallback(
(e: ChangeEvent<HTMLSelectElement>) => {
dispatch(modelSelected(e.target.value));
},
[dispatch]
);
// const handleChangeModel = useCallback(
// (v: string | null | undefined) => {
// if (!v) {
// return;
// }
// dispatch(modelSelected(v));
// (e: ChangeEvent<HTMLSelectElement>) => {
// dispatch(modelSelected(e.target.value));
// },
// [dispatch]
// );
const handleChangeModel = useCallback(
(v: string | null) => {
if (!v) {
return;
}
dispatch(modelSelected(v));
},
[dispatch]
);
return (
<IAIMantineSelect