added optional popovers for users to learn more about each setting

This commit is contained in:
Jennifer Player 2023-09-15 10:37:05 -04:00
parent 7b2e6deaf1
commit fcea65770f
59 changed files with 1018 additions and 360 deletions

View File

@ -653,6 +653,132 @@
"infillAndScaling": "Manage infill methods (used on masked or erased areas of the canvas) and scaling (useful for small bounding box sizes)." "infillAndScaling": "Manage infill methods (used on masked or erased areas of the canvas) and scaling (useful for small bounding box sizes)."
} }
}, },
"popovers": {
"clipSkip": {
"heading": "CLIP Skip",
"paragraph": "Choose how many layers of the CLIP model to skip. Certain models are better suited to be used with CLIP Skip."
},
"compositingBlur": {
"heading": "Blur",
"paragraph": "The blur radius of the mask."
},
"compositingBlurMethod": {
"heading": "Blur Method",
"paragraph": "The method of blur applied to the masked area."
},
"compositingCoherencePass": {
"heading": "Coherence Pass",
"paragraph": "Composite the Inpainted/Outpainted images."
},
"compositingMode": {
"heading": "Mode",
"paragraph": "The mode of the Coherence Pass."
},
"compositingSteps": {
"heading": "Steps",
"paragraph": "Number of steps in the Coherence Pass. Similar to Denoising Steps."
},
"compositingStrength": {
"heading": "Strength",
"paragraph": "Amount of noise added for the Coherence Pass. Similar to Denoising Strength."
},
"compositingMaskAdjustments": {
"heading": "Mask Adjustments",
"paragraph": "Adjust the mask."
},
"controlNetBeginEnd": {
"heading": "Begin / End Step Percentage",
"paragraph": "Which parts of the denoising process will have the ControlNet applied. ControlNets applied at the start of the process guide composition, and ControlNets applied at the end guide details."
},
"controlNetControlMode": {
"heading": "Control Mode",
"paragraph": "Lends more weight to either the prompt or ControlNet."
},
"controlNetResizeMode": {
"heading": "Resize Mode",
"paragraph": "How the ControlNet image will be fit to the image generation Ratio"
},
"controlNetToggle": {
"heading": "Enable ControlNet",
"paragraph": "ControlNets provide guidance to the generation process, helping create images with controlled composition, structure, or style, depending on the model selected."
},
"controlNetWeight": {
"heading": "Weight",
"paragraph": "How strongly the ControlNet will impact the generated image."
},
"dynamicPromptsToggle": {
"heading": "Enable Dynamic Prompts",
"paragraph": "Dynamic prompts allow multiple options within a prompt. Dynamic prompts can be used by: {option1|option2|option3}. Combinations of prompts will be randomly generated until the “Images” number has been reached."
},
"dynamicPromptsCombinatorial": {
"heading": "Combinatorial Generation",
"paragraph": "Generate an image for every possible combination of Dynamic Prompt until the Max Prompts is reached."
},
"infillMethod": {
"heading": "Infill Method",
"paragraph": "Method to infill the selected area."
},
"lora": {
"heading": "LoRA",
"paragraph": "Weight of the LoRA. Higher weight will lead to larger impacts on the final image."
},
"noiseEnable": {
"heading": "Enable Noise Settings",
"paragraph": "Advanced control over noise generation."
},
"noiseUseCPU": {
"heading": "Use CPU Noise",
"paragraph": "Uses the CPU to generate random noise."
},
"paramsCFGScale": {
"heading": "CFG Scale",
"paragraph": "Controls how much your prompt influences the generation process."
},
"paramDenoisingStrength": {
"heading": "Denoising Strength",
"paragraph": "How much noise is added to the input image. 0 will result in an identical image, while 1 will result in a completely new image."
},
"paramImages": {
"heading": "Images",
"paragraph": "Number of images that will be generated."
},
"paramModel": {
"heading": "Model",
"paragraph": "Model used for the denoising steps. Different models are trained to specialize in producing different aesthetic results and content."
},
"paramPositiveConditioning": {
"heading": "Positive Prompts",
"paragraph": "This is where you enter your positive prompts."
},
"paramScheduler": {
"heading": "Scheduler",
"paragraph": "Scheduler defines how to iteratively add noise to an image or how to update a sample based on a model's output."
},
"paramSeed": {
"heading": "Seed",
"paragraph": "Controls the starting noise used for generation. Disable “Random Seed” to produce identical results with the same generation settings."
},
"paramNegativeConditioning": {
"heading": "Negative Prompts",
"paragraph": "This is where you enter your negative prompts."
},
"paramSteps": {
"heading": "Steps",
"paragraph": "Number of steps that will be performed in each generation. Higher step counts will typically create better images but will require more generation time."
},
"paramVAE": {
"heading": "VAE",
"paragraph": "Model used for translating AI output into the final image."
},
"paramVAEPrecision": {
"heading": "VAE Precision",
"paragraph": "The precision used during VAE encoding and decoding. Fp16/Half precision is more efficient, at the expense of minor image variations."
},
"scaleBeforeProcessing": {
"heading": "Scale Before Processing",
"paragraph": "Scales the selected area to the size best suited for the model before the image generation process."
}
},
"unifiedCanvas": { "unifiedCanvas": {
"layer": "Layer", "layer": "Layer",
"base": "Base", "base": "Base",

View File

@ -17,12 +17,13 @@ import { useAppSelector } from '../../app/store/storeHooks';
import { systemSelector } from '../../features/system/store/systemSelectors'; import { systemSelector } from '../../features/system/store/systemSelectors';
interface Props extends PopoverProps { interface Props extends PopoverProps {
heading: string; heading?: string;
paragraph: string; paragraph: string;
triggerComponent: ReactNode; triggerComponent: ReactNode;
image?: string; image?: string;
buttonLabel?: string; buttonLabel?: string;
buttonHref?: string; buttonHref?: string;
placement?: string;
} }
function IAIInformationalPopover({ function IAIInformationalPopover({
@ -32,6 +33,7 @@ function IAIInformationalPopover({
buttonLabel, buttonLabel,
buttonHref, buttonHref,
triggerComponent, triggerComponent,
placement,
}: Props) { }: Props) {
const { shouldDisableInformationalPopovers } = useAppSelector(systemSelector); const { shouldDisableInformationalPopovers } = useAppSelector(systemSelector);
@ -40,7 +42,7 @@ function IAIInformationalPopover({
} else { } else {
return ( return (
<Popover <Popover
placement="top" placement={placement || 'top'}
closeOnBlur={false} closeOnBlur={false}
trigger="hover" trigger="hover"
variant="informational" variant="informational"
@ -58,14 +60,15 @@ function IAIInformationalPopover({
gap: 3, gap: 3,
flexDirection: 'column', flexDirection: 'column',
width: '100%', width: '100%',
alignItems: 'center',
}} }}
> >
{image && ( {image && (
<Image <Image
sx={{ sx={{
objectFit: 'contain', objectFit: 'contain',
maxW: '100%', maxW: '60%',
maxH: 'full', maxH: '60%',
backgroundColor: 'white', backgroundColor: 'white',
}} }}
src={image} src={image}
@ -78,13 +81,13 @@ function IAIInformationalPopover({
flexDirection: 'column', flexDirection: 'column',
p: 3, p: 3,
pt: 0, pt: heading ? 0 : 3,
}} }}
> >
<PopoverHeader>{heading}</PopoverHeader> {heading && <PopoverHeader>{heading}</PopoverHeader>}
<Text sx={{ pl: 3, pr: 3 }}>{paragraph}</Text> <Text sx={{ px: 3 }}>{paragraph}</Text>
{buttonLabel && ( {buttonLabel && (
<Flex sx={{ pl: 3, pr: 3 }} justifyContent="flex-end"> <Flex sx={{ px: 3 }} justifyContent="flex-end">
<Button <Button
onClick={() => window.open(buttonHref)} onClick={() => window.open(buttonHref)}
size="sm" size="sm"

View File

@ -15,6 +15,7 @@ import {
controlNetBeginStepPctChanged, controlNetBeginStepPctChanged,
controlNetEndStepPctChanged, controlNetEndStepPctChanged,
} from 'features/controlNet/store/controlNetSlice'; } from 'features/controlNet/store/controlNetSlice';
import { ControlNetBeginEndPopover } from 'features/informationalPopovers/components/controlNetBeginEnd';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
type Props = { type Props = {
@ -47,58 +48,60 @@ const ParamControlNetBeginEnd = (props: Props) => {
); );
return ( return (
<FormControl isDisabled={!isEnabled}> <ControlNetBeginEndPopover>
<FormLabel>Begin / End Step Percentage</FormLabel> <FormControl isDisabled={!isEnabled}>
<HStack w="100%" gap={2} alignItems="center"> <FormLabel>Begin / End Step Percentage</FormLabel>
<RangeSlider <HStack w="100%" gap={2} alignItems="center">
aria-label={['Begin Step %', 'End Step %']} <RangeSlider
value={[beginStepPct, endStepPct]} aria-label={['Begin Step %', 'End Step %']}
onChange={handleStepPctChanged} value={[beginStepPct, endStepPct]}
min={0} onChange={handleStepPctChanged}
max={1} min={0}
step={0.01} max={1}
minStepsBetweenThumbs={5} step={0.01}
isDisabled={!isEnabled} minStepsBetweenThumbs={5}
> isDisabled={!isEnabled}
<RangeSliderTrack>
<RangeSliderFilledTrack />
</RangeSliderTrack>
<Tooltip label={formatPct(beginStepPct)} placement="top" hasArrow>
<RangeSliderThumb index={0} />
</Tooltip>
<Tooltip label={formatPct(endStepPct)} placement="top" hasArrow>
<RangeSliderThumb index={1} />
</Tooltip>
<RangeSliderMark
value={0}
sx={{
insetInlineStart: '0 !important',
insetInlineEnd: 'unset !important',
}}
> >
0% <RangeSliderTrack>
</RangeSliderMark> <RangeSliderFilledTrack />
<RangeSliderMark </RangeSliderTrack>
value={0.5} <Tooltip label={formatPct(beginStepPct)} placement="top" hasArrow>
sx={{ <RangeSliderThumb index={0} />
insetInlineStart: '50% !important', </Tooltip>
transform: 'translateX(-50%)', <Tooltip label={formatPct(endStepPct)} placement="top" hasArrow>
}} <RangeSliderThumb index={1} />
> </Tooltip>
50% <RangeSliderMark
</RangeSliderMark> value={0}
<RangeSliderMark sx={{
value={1} insetInlineStart: '0 !important',
sx={{ insetInlineEnd: 'unset !important',
insetInlineStart: 'unset !important', }}
insetInlineEnd: '0 !important', >
}} 0%
> </RangeSliderMark>
100% <RangeSliderMark
</RangeSliderMark> value={0.5}
</RangeSlider> sx={{
</HStack> insetInlineStart: '50% !important',
</FormControl> transform: 'translateX(-50%)',
}}
>
50%
</RangeSliderMark>
<RangeSliderMark
value={1}
sx={{
insetInlineStart: 'unset !important',
insetInlineEnd: '0 !important',
}}
>
100%
</RangeSliderMark>
</RangeSlider>
</HStack>
</FormControl>
</ControlNetBeginEndPopover>
); );
}; };

View File

@ -5,6 +5,7 @@ import {
ControlNetConfig, ControlNetConfig,
controlNetControlModeChanged, controlNetControlModeChanged,
} from 'features/controlNet/store/controlNetSlice'; } from 'features/controlNet/store/controlNetSlice';
import { ControlNetControlModePopover } from 'features/informationalPopovers/components/controlNetControlMode';
import { useCallback } from 'react'; import { useCallback } from 'react';
type ParamControlNetControlModeProps = { type ParamControlNetControlModeProps = {
@ -32,12 +33,14 @@ export default function ParamControlNetControlMode(
); );
return ( return (
<IAIMantineSelect <ControlNetControlModePopover>
disabled={!isEnabled} <IAIMantineSelect
label="Control Mode" disabled={!isEnabled}
data={CONTROL_MODE_DATA} label="Control Mode"
value={String(controlMode)} data={CONTROL_MODE_DATA}
onChange={handleControlModeChange} value={String(controlMode)}
/> onChange={handleControlModeChange}
/>
</ControlNetControlModePopover>
); );
} }

View File

@ -4,6 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { isControlNetEnabledToggled } from 'features/controlNet/store/controlNetSlice'; import { isControlNetEnabledToggled } from 'features/controlNet/store/controlNetSlice';
import { ControlNetTogglePopover } from 'features/informationalPopovers/components/controlnetToggle';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
const selector = createSelector( const selector = createSelector(
@ -25,14 +26,16 @@ const ParamControlNetFeatureToggle = () => {
}, [dispatch]); }, [dispatch]);
return ( return (
<IAISwitch <ControlNetTogglePopover>
label="Enable ControlNet" <IAISwitch
isChecked={isEnabled} label="Enable ControlNet"
onChange={handleChange} isChecked={isEnabled}
formControlProps={{ onChange={handleChange}
width: '100%', formControlProps={{
}} width: '100%',
/> }}
/>
</ControlNetTogglePopover>
); );
}; };

View File

@ -5,6 +5,7 @@ import {
ResizeModes, ResizeModes,
controlNetResizeModeChanged, controlNetResizeModeChanged,
} from 'features/controlNet/store/controlNetSlice'; } from 'features/controlNet/store/controlNetSlice';
import { ControlNetResizeModePopover } from 'features/informationalPopovers/components/controlNetResizeMode';
import { useCallback } from 'react'; import { useCallback } from 'react';
type ParamControlNetResizeModeProps = { type ParamControlNetResizeModeProps = {
@ -31,12 +32,14 @@ export default function ParamControlNetResizeMode(
); );
return ( return (
<IAIMantineSelect <ControlNetResizeModePopover>
disabled={!isEnabled} <IAIMantineSelect
label="Resize Mode" disabled={!isEnabled}
data={RESIZE_MODE_DATA} label="Resize Mode"
value={String(resizeMode)} data={RESIZE_MODE_DATA}
onChange={handleResizeModeChange} value={String(resizeMode)}
/> onChange={handleResizeModeChange}
/>
</ControlNetResizeModePopover>
); );
} }

View File

@ -4,6 +4,7 @@ import {
ControlNetConfig, ControlNetConfig,
controlNetWeightChanged, controlNetWeightChanged,
} from 'features/controlNet/store/controlNetSlice'; } from 'features/controlNet/store/controlNetSlice';
import { ControlNetWeightPopover } from 'features/informationalPopovers/components/controlNetWeight';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
type ParamControlNetWeightProps = { type ParamControlNetWeightProps = {
@ -21,17 +22,19 @@ const ParamControlNetWeight = (props: ParamControlNetWeightProps) => {
); );
return ( return (
<IAISlider <ControlNetWeightPopover>
isDisabled={!isEnabled} <IAISlider
label="Weight" isDisabled={!isEnabled}
value={weight} label="Weight"
onChange={handleWeightChanged} value={weight}
min={0} onChange={handleWeightChanged}
max={2} min={0}
step={0.01} max={2}
withSliderMarks step={0.01}
sliderMarks={[0, 1, 2]} withSliderMarks
/> sliderMarks={[0, 1, 2]}
/>
</ControlNetWeightPopover>
); );
}; };

View File

@ -5,6 +5,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { combinatorialToggled } from '../store/dynamicPromptsSlice'; import { combinatorialToggled } from '../store/dynamicPromptsSlice';
import { DynamicPromptsCombinatorialPopover } from 'features/informationalPopovers/components/dynamicPromptsCombinatorial';
const selector = createSelector( const selector = createSelector(
stateSelector, stateSelector,
@ -25,12 +26,14 @@ const ParamDynamicPromptsCombinatorial = () => {
}, [dispatch]); }, [dispatch]);
return ( return (
<IAISwitch <DynamicPromptsCombinatorialPopover>
isDisabled={isDisabled} <IAISwitch
label="Combinatorial Generation" isDisabled={isDisabled}
isChecked={combinatorial} label="Combinatorial Generation"
onChange={handleChange} isChecked={combinatorial}
/> onChange={handleChange}
/>
</DynamicPromptsCombinatorialPopover>
); );
}; };

View File

@ -5,6 +5,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { isEnabledToggled } from '../store/dynamicPromptsSlice'; import { isEnabledToggled } from '../store/dynamicPromptsSlice';
import { DynamicPromptsTogglePopover } from 'features/informationalPopovers/components/dynamicPromptsToggle';
const selector = createSelector( const selector = createSelector(
stateSelector, stateSelector,
@ -25,11 +26,13 @@ const ParamDynamicPromptsToggle = () => {
}, [dispatch]); }, [dispatch]);
return ( return (
<IAISwitch <DynamicPromptsTogglePopover>
label="Enable Dynamic Prompts" <IAISwitch
isChecked={isEnabled} label="Enable Dynamic Prompts"
onChange={handleToggleIsEnabled} isChecked={isEnabled}
/> onChange={handleToggleIsEnabled}
/>
</DynamicPromptsTogglePopover>
); );
}; };

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ClipSkipPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.clipSkip.paragraph')}
heading={t('popovers.clipSkip.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingBlurPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingBlur.paragraph')}
heading={t('popovers.compositingBlur.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingBlurMethodPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingBlurMethod.paragraph')}
heading={t('popovers.compositingBlurMethod.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingCoherencePassPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingCoherencePass.paragraph')}
heading={t('popovers.compositingCoherencePass.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingModePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingMode.paragraph')}
heading={t('popovers.compositingMode.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingStepsPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingSteps.paragraph')}
heading={t('popovers.compositingSteps.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingStrengthPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingStrength.paragraph')}
heading={t('popovers.compositingStrength.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const CompositingMaskAdjustmentsPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.compositingMaskAdjustments.paragraph')}
heading={t('popovers.compositingMaskAdjustments.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ControlNetBeginEndPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.controlNetBeginEnd.paragraph')}
heading={t('popovers.controlNetBeginEnd.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ControlNetControlModePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.controlNetControlMode.paragraph')}
heading={t('popovers.controlNetControlMode.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ControlNetResizeModePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.controlNetResizeMode.paragraph')}
heading={t('popovers.controlNetResizeMode.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ControlNetTogglePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.controlNetToggle.paragraph')}
heading={t('popovers.controlNetToggle.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ControlNetWeightPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.controlNetWeight.paragraph')}
heading={t('popovers.controlNetWeight.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,17 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const DynamicPromptsCombinatorialPopover = (
props: PropsWithChildren
) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.dynamicPromptsCombinatorial.paragraph')}
heading={t('popovers.dynamicPromptsCombinatorial.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const DynamicPromptsTogglePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.dynamicPromptsToggle.paragraph')}
heading={t('popovers.dynamicPromptsToggle.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const InfillMethodPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.infillMethod.paragraph')}
heading={t('popovers.infillMethod.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const LoraPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.lora.paragraph')}
heading={t('popovers.lora.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const NoiseEnablePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.noiseEnable.paragraph')}
heading={t('popovers.noiseEnable.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const NoiseUseCPUPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.noiseUseCPU.paragraph')}
heading={t('popovers.noiseUseCPU.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamCFGScalePopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramsCFGScale.paragraph')}
heading={t('popovers.paramsCFGScale.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamDenoisingStrengthPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramsDenoisingStrength.paragraph')}
heading={t('popovers.paramsDenoisingStrength.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamImagesPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramImages.paragraph')}
heading={t('popovers.paramImages.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamModelPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramModel.paragraph')}
heading={t('popovers.paramModel.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -1,12 +1,15 @@
import { PropsWithChildren } from 'react'; import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover'; import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import InvokeAILogoImage from 'assets/images/logo.png'; import InvokeAILogoImage from 'assets/images/logo.png';
import { useTranslation } from 'react-i18next';
export const ParamPositiveConditioningPopover = (props: PropsWithChildren) => { export const ParamPositiveConditioningPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return ( return (
<IAIInformationalPopover <IAIInformationalPopover
heading="Prompt Box" paragraph={t('popovers.paramPositiveConditioning.paragraph')}
paragraph="This is where you enter your prompt" heading={t('popovers.paramPositiveConditioning.heading')}
buttonLabel="Learn more" buttonLabel="Learn more"
buttonHref="http://google.com" buttonHref="http://google.com"
image={InvokeAILogoImage} image={InvokeAILogoImage}

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamSchedulerPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramScheduler.paragraph')}
heading={t('popovers.paramScheduler.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamSeedPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramSeed.paragraph')}
heading={t('popovers.paramSeed.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamStepsPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramSteps.paragraph')}
heading={t('popovers.paramSteps.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamVAEPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramVAE.paragraph')}
heading={t('popovers.paramVAE.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ParamVAEPrecisionPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.paramVAEPrecision.paragraph')}
heading={t('popovers.paramVAEPrecision.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react';
import IAIInformationalPopover from '../../../common/components/IAIInformationalPopover';
import { useTranslation } from 'react-i18next';
export const ScaleBeforeProcessingPopover = (props: PropsWithChildren) => {
const { t } = useTranslation();
return (
<IAIInformationalPopover
paragraph={t('popovers.scaleBeforeProcessing.paragraph')}
heading={t('popovers.scaleBeforeProcessing.heading')}
triggerComponent={props.children}
/>
);
};

View File

@ -10,6 +10,7 @@ import {
loraWeightChanged, loraWeightChanged,
loraWeightReset, loraWeightReset,
} from '../store/loraSlice'; } from '../store/loraSlice';
import { LoraPopover } from 'features/informationalPopovers/components/lora';
type Props = { type Props = {
lora: LoRA; lora: LoRA;
@ -35,30 +36,32 @@ const ParamLora = (props: Props) => {
}, [dispatch, lora.id]); }, [dispatch, lora.id]);
return ( return (
<Flex sx={{ gap: 2.5, alignItems: 'flex-end' }}> <LoraPopover>
<IAISlider <Flex sx={{ gap: 2.5, alignItems: 'flex-end' }}>
label={lora.model_name} <IAISlider
value={lora.weight} label={lora.model_name}
onChange={handleChange} value={lora.weight}
min={-1} onChange={handleChange}
max={2} min={-1}
step={0.01} max={2}
withInput step={0.01}
withReset withInput
handleReset={handleReset} withReset
withSliderMarks handleReset={handleReset}
sliderMarks={[-1, 0, 1, 2]} withSliderMarks
sliderNumberInputProps={{ min: -50, max: 50 }} sliderMarks={[-1, 0, 1, 2]}
/> sliderNumberInputProps={{ min: -50, max: 50 }}
<IAIIconButton />
size="sm" <IAIIconButton
onClick={handleRemoveLora} size="sm"
tooltip="Remove LoRA" onClick={handleRemoveLora}
aria-label="Remove LoRA" tooltip="Remove LoRA"
icon={<FaTrash />} aria-label="Remove LoRA"
colorScheme="error" icon={<FaTrash />}
/> colorScheme="error"
</Flex> />
</Flex>
</LoraPopover>
); );
}; };

View File

@ -1,6 +1,7 @@
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { ClipSkipPopover } from 'features/informationalPopovers/components/clipSkip';
import { setClipSkip } from 'features/parameters/store/generationSlice'; import { setClipSkip } from 'features/parameters/store/generationSlice';
import { clipSkipMap } from 'features/parameters/types/constants'; import { clipSkipMap } from 'features/parameters/types/constants';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
@ -42,19 +43,21 @@ export default function ParamClipSkip() {
}, [model]); }, [model]);
return ( return (
<IAISlider <ClipSkipPopover>
label={t('parameters.clipSkip')} <IAISlider
aria-label={t('parameters.clipSkip')} label={t('parameters.clipSkip')}
min={0} aria-label={t('parameters.clipSkip')}
max={max} min={0}
step={1} max={max}
value={clipSkip} step={1}
onChange={handleClipSkipChange} value={clipSkip}
withSliderMarks onChange={handleClipSkipChange}
sliderMarks={sliderMarks} withSliderMarks
withInput sliderMarks={sliderMarks}
withReset withInput
handleReset={handleClipSkipReset} withReset
/> handleReset={handleClipSkipReset}
/>
</ClipSkipPopover>
); );
} }

View File

@ -2,6 +2,7 @@ import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect'; import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect';
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { CompositingModePopover } from 'features/informationalPopovers/components/compositingMode';
import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice'; import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice';
import { CanvasCoherenceModeParam } from 'features/parameters/types/parameterSchemas'; import { CanvasCoherenceModeParam } from 'features/parameters/types/parameterSchemas';
@ -30,12 +31,14 @@ const ParamCanvasCoherenceMode = () => {
}; };
return ( return (
<IAIMantineSelect <CompositingModePopover>
label={t('parameters.coherenceMode')} <IAIMantineSelect
data={coherenceModeSelectData} label={t('parameters.coherenceMode')}
value={canvasCoherenceMode} data={coherenceModeSelectData}
onChange={handleCoherenceModeChange} value={canvasCoherenceMode}
/> onChange={handleCoherenceModeChange}
/>
</CompositingModePopover>
); );
}; };

View File

@ -1,6 +1,7 @@
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { CompositingStepsPopover } from 'features/informationalPopovers/components/compositingSteps';
import { setCanvasCoherenceSteps } from 'features/parameters/store/generationSlice'; import { setCanvasCoherenceSteps } from 'features/parameters/store/generationSlice';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -13,23 +14,25 @@ const ParamCanvasCoherenceSteps = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<IAISlider <CompositingStepsPopover>
label={t('parameters.coherenceSteps')} <IAISlider
min={1} label={t('parameters.coherenceSteps')}
max={100} min={1}
step={1} max={100}
sliderNumberInputProps={{ max: 999 }} step={1}
value={canvasCoherenceSteps} sliderNumberInputProps={{ max: 999 }}
onChange={(v) => { value={canvasCoherenceSteps}
dispatch(setCanvasCoherenceSteps(v)); onChange={(v) => {
}} dispatch(setCanvasCoherenceSteps(v));
withInput }}
withSliderMarks withInput
withReset withSliderMarks
handleReset={() => { withReset
dispatch(setCanvasCoherenceSteps(20)); handleReset={() => {
}} dispatch(setCanvasCoherenceSteps(20));
/> }}
/>
</CompositingStepsPopover>
); );
}; };

View File

@ -1,6 +1,7 @@
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { CompositingStrengthPopover } from 'features/informationalPopovers/components/compositingStrength';
import { setCanvasCoherenceStrength } from 'features/parameters/store/generationSlice'; import { setCanvasCoherenceStrength } from 'features/parameters/store/generationSlice';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -13,23 +14,25 @@ const ParamCanvasCoherenceStrength = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<IAISlider <CompositingStrengthPopover>
label={t('parameters.coherenceStrength')} <IAISlider
min={0} label={t('parameters.coherenceStrength')}
max={1} min={0}
step={0.01} max={1}
sliderNumberInputProps={{ max: 999 }} step={0.01}
value={canvasCoherenceStrength} sliderNumberInputProps={{ max: 999 }}
onChange={(v) => { value={canvasCoherenceStrength}
dispatch(setCanvasCoherenceStrength(v)); onChange={(v) => {
}} dispatch(setCanvasCoherenceStrength(v));
withInput }}
withSliderMarks withInput
withReset withSliderMarks
handleReset={() => { withReset
dispatch(setCanvasCoherenceStrength(0.3)); handleReset={() => {
}} dispatch(setCanvasCoherenceStrength(0.3));
/> }}
/>
</CompositingStrengthPopover>
); );
}; };

View File

@ -1,6 +1,7 @@
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { CompositingBlurPopover } from 'features/informationalPopovers/components/compositingBlur';
import { setMaskBlur } from 'features/parameters/store/generationSlice'; import { setMaskBlur } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -12,21 +13,23 @@ export default function ParamMaskBlur() {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<IAISlider <CompositingBlurPopover>
label={t('parameters.maskBlur')} <IAISlider
min={0} label={t('parameters.maskBlur')}
max={64} min={0}
sliderNumberInputProps={{ max: 512 }} max={64}
value={maskBlur} sliderNumberInputProps={{ max: 512 }}
onChange={(v) => { value={maskBlur}
dispatch(setMaskBlur(v)); onChange={(v) => {
}} dispatch(setMaskBlur(v));
withInput }}
withSliderMarks withInput
withReset withSliderMarks
handleReset={() => { withReset
dispatch(setMaskBlur(16)); handleReset={() => {
}} dispatch(setMaskBlur(16));
/> }}
/>
</CompositingBlurPopover>
); );
} }

View File

@ -3,6 +3,7 @@ import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { CompositingBlurMethodPopover } from 'features/informationalPopovers/components/compositingBlurMethod';
import { setMaskBlurMethod } from 'features/parameters/store/generationSlice'; import { setMaskBlurMethod } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -28,11 +29,13 @@ export default function ParamMaskBlurMethod() {
}; };
return ( return (
<IAIMantineSelect <CompositingBlurMethodPopover>
value={maskBlurMethod} <IAIMantineSelect
onChange={handleMaskBlurMethodChange} value={maskBlurMethod}
label={t('parameters.maskBlurMethod')} onChange={handleMaskBlurMethodChange}
data={maskBlurMethods} label={t('parameters.maskBlurMethod')}
/> data={maskBlurMethods}
/>
</CompositingBlurMethodPopover>
); );
} }

View File

@ -3,6 +3,7 @@ import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { InfillMethodPopover } from 'features/informationalPopovers/components/infillMethod';
import { setInfillMethod } from 'features/parameters/store/generationSlice'; import { setInfillMethod } from 'features/parameters/store/generationSlice';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
@ -39,14 +40,16 @@ const ParamInfillMethod = () => {
); );
return ( return (
<IAIMantineSelect <InfillMethodPopover>
disabled={infill_methods?.length === 0} <IAIMantineSelect
placeholder={isLoading ? 'Loading...' : undefined} disabled={infill_methods?.length === 0}
label={t('parameters.infillMethod')} placeholder={isLoading ? 'Loading...' : undefined}
value={infillMethod} label={t('parameters.infillMethod')}
data={infill_methods ?? []} value={infillMethod}
onChange={handleChange} data={infill_methods ?? []}
/> onChange={handleChange}
/>
</InfillMethodPopover>
); );
}; };

View File

@ -8,6 +8,7 @@ import {
BOUNDING_BOX_SCALES_DICT, BOUNDING_BOX_SCALES_DICT,
BoundingBoxScale, BoundingBoxScale,
} from 'features/canvas/store/canvasTypes'; } from 'features/canvas/store/canvasTypes';
import { ScaleBeforeProcessingPopover } from 'features/informationalPopovers/components/scaleBeforeProcessing';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -35,12 +36,14 @@ const ParamScaleBeforeProcessing = () => {
}; };
return ( return (
<IAIMantineSearchableSelect <ScaleBeforeProcessingPopover>
label={t('parameters.scaleBeforeProcessing')} <IAIMantineSearchableSelect
data={BOUNDING_BOX_SCALES_DICT} label={t('parameters.scaleBeforeProcessing')}
value={boundingBoxScale} data={BOUNDING_BOX_SCALES_DICT}
onChange={handleChangeBoundingBoxScaleMethod} value={boundingBoxScale}
/> onChange={handleChangeBoundingBoxScaleMethod}
/>
</ScaleBeforeProcessingPopover>
); );
}; };

View File

@ -4,6 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { ParamCFGScalePopover } from 'features/informationalPopovers/components/paramCFGScale';
import { setCfgScale } from 'features/parameters/store/generationSlice'; import { setCfgScale } from 'features/parameters/store/generationSlice';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -53,31 +54,35 @@ const ParamCFGScale = () => {
); );
return shouldUseSliders ? ( return shouldUseSliders ? (
<IAISlider <ParamCFGScalePopover>
label={t('parameters.cfgScale')} <IAISlider
step={shift ? 0.1 : 0.5} label={t('parameters.cfgScale')}
min={min} step={shift ? 0.1 : 0.5}
max={sliderMax} min={min}
onChange={handleChange} max={sliderMax}
handleReset={handleReset} onChange={handleChange}
value={cfgScale} handleReset={handleReset}
sliderNumberInputProps={{ max: inputMax }} value={cfgScale}
withInput sliderNumberInputProps={{ max: inputMax }}
withReset withInput
withSliderMarks withReset
isInteger={false} withSliderMarks
/> isInteger={false}
/>
</ParamCFGScalePopover>
) : ( ) : (
<IAINumberInput <ParamCFGScalePopover>
label={t('parameters.cfgScale')} <IAINumberInput
step={0.5} label={t('parameters.cfgScale')}
min={min} step={0.5}
max={inputMax} min={min}
onChange={handleChange} max={inputMax}
value={cfgScale} onChange={handleChange}
isInteger={false} value={cfgScale}
numberInputFieldProps={{ textAlign: 'center' }} isInteger={false}
/> numberInputFieldProps={{ textAlign: 'center' }}
/>
</ParamCFGScalePopover>
); );
}; };

View File

@ -4,6 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { ParamImagesPopover } from 'features/informationalPopovers/components/paramImages';
import { setIterations } from 'features/parameters/store/generationSlice'; import { setIterations } from 'features/parameters/store/generationSlice';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -60,31 +61,35 @@ const ParamIterations = () => {
}, [dispatch, initial]); }, [dispatch, initial]);
return shouldUseSliders ? ( return shouldUseSliders ? (
<IAISlider <ParamImagesPopover>
isDisabled={isDisabled} <IAISlider
label={t('parameters.images')} isDisabled={isDisabled}
step={step} label={t('parameters.images')}
min={min} step={step}
max={sliderMax} min={min}
onChange={handleChange} max={sliderMax}
handleReset={handleReset} onChange={handleChange}
value={iterations} handleReset={handleReset}
withInput value={iterations}
withReset withInput
withSliderMarks withReset
sliderNumberInputProps={{ max: inputMax }} withSliderMarks
/> sliderNumberInputProps={{ max: inputMax }}
/>
</ParamImagesPopover>
) : ( ) : (
<IAINumberInput <ParamImagesPopover>
isDisabled={isDisabled} <IAINumberInput
label={t('parameters.images')} isDisabled={isDisabled}
step={step} label={t('parameters.images')}
min={min} step={step}
max={inputMax} min={min}
onChange={handleChange} max={inputMax}
value={iterations} onChange={handleChange}
numberInputFieldProps={{ textAlign: 'center' }} value={iterations}
/> numberInputFieldProps={{ textAlign: 'center' }}
/>
</ParamImagesPopover>
); );
}; };

View File

@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect'; import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
import { ParamSchedulerPopover } from 'features/informationalPopovers/components/paramScheduler';
import { generationSelector } from 'features/parameters/store/generationSelectors'; import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setScheduler } from 'features/parameters/store/generationSlice'; import { setScheduler } from 'features/parameters/store/generationSlice';
import { import {
@ -51,12 +52,14 @@ const ParamScheduler = () => {
); );
return ( return (
<IAIMantineSearchableSelect <ParamSchedulerPopover>
label={t('parameters.scheduler')} <IAIMantineSearchableSelect
value={scheduler} label={t('parameters.scheduler')}
data={data} value={scheduler}
onChange={handleChange} data={data}
/> onChange={handleChange}
/>
</ParamSchedulerPopover>
); );
}; };

View File

@ -5,6 +5,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { ParamStepsPopover } from 'features/informationalPopovers/components/paramSteps';
import { import {
clampSymmetrySteps, clampSymmetrySteps,
setSteps, setSteps,
@ -56,30 +57,34 @@ const ParamSteps = () => {
}, [dispatch]); }, [dispatch]);
return shouldUseSliders ? ( return shouldUseSliders ? (
<IAISlider <ParamStepsPopover>
label={t('parameters.steps')} <IAISlider
min={min} label={t('parameters.steps')}
max={sliderMax} min={min}
step={step} max={sliderMax}
onChange={handleChange} step={step}
handleReset={handleReset} onChange={handleChange}
value={steps} handleReset={handleReset}
withInput value={steps}
withReset withInput
withSliderMarks withReset
sliderNumberInputProps={{ max: inputMax }} withSliderMarks
/> sliderNumberInputProps={{ max: inputMax }}
/>
</ParamStepsPopover>
) : ( ) : (
<IAINumberInput <ParamStepsPopover>
label={t('parameters.steps')} <IAINumberInput
min={min} label={t('parameters.steps')}
max={inputMax} min={min}
step={step} max={inputMax}
onChange={handleChange} step={step}
value={steps} onChange={handleChange}
numberInputFieldProps={{ textAlign: 'center' }} value={steps}
onBlur={handleBlur} numberInputFieldProps={{ textAlign: 'center' }}
/> onBlur={handleBlur}
/>
</ParamStepsPopover>
); );
}; };

View File

@ -21,6 +21,7 @@ import {
useGetOnnxModelsQuery, useGetOnnxModelsQuery,
} from 'services/api/endpoints/models'; } from 'services/api/endpoints/models';
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus'; import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
import { ParamModelPopover } from 'features/informationalPopovers/components/paramModel';
const selector = createSelector( const selector = createSelector(
stateSelector, stateSelector,
@ -118,24 +119,28 @@ const ParamMainModelSelect = () => {
data={[]} data={[]}
/> />
) : ( ) : (
<Flex w="100%" alignItems="center" gap={3}> <ParamModelPopover>
<IAIMantineSearchableSelect <Flex w="100%" alignItems="center" gap={3}>
tooltip={selectedModel?.description} <IAIMantineSearchableSelect
label={t('modelManager.model')} tooltip={selectedModel?.description}
value={selectedModel?.id} label={t('modelManager.model')}
placeholder={data.length > 0 ? 'Select a model' : 'No models available'} value={selectedModel?.id}
data={data} placeholder={
error={data.length === 0} data.length > 0 ? 'Select a model' : 'No models available'
disabled={data.length === 0} }
onChange={handleChangeModel} data={data}
w="100%" error={data.length === 0}
/> disabled={data.length === 0}
{isSyncModelEnabled && ( onChange={handleChangeModel}
<Box mt={7}> w="100%"
<SyncModelsButton iconMode /> />
</Box> {isSyncModelEnabled && (
)} <Box mt={7}>
</Flex> <SyncModelsButton iconMode />
</Box>
)}
</Flex>
</ParamModelPopover>
); );
}; };

View File

@ -3,6 +3,7 @@ import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { NoiseUseCPUPopover } from 'features/informationalPopovers/components/noiseUseCPU';
import { shouldUseCpuNoiseChanged } from 'features/parameters/store/generationSlice'; import { shouldUseCpuNoiseChanged } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
@ -26,11 +27,13 @@ export const ParamCpuNoiseToggle = () => {
dispatch(shouldUseCpuNoiseChanged(e.target.checked)); dispatch(shouldUseCpuNoiseChanged(e.target.checked));
return ( return (
<IAISwitch <NoiseUseCPUPopover>
isDisabled={isDisabled} <IAISwitch
label="Use CPU Noise" isDisabled={isDisabled}
isChecked={shouldUseCpuNoise} label="Use CPU Noise"
onChange={handleChange} isChecked={shouldUseCpuNoise}
/> onChange={handleChange}
/>
</NoiseUseCPUPopover>
); );
}; };

View File

@ -1,6 +1,7 @@
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { NoiseEnablePopover } from 'features/informationalPopovers/components/noiseEnable';
import { setShouldUseNoiseSettings } from 'features/parameters/store/generationSlice'; import { setShouldUseNoiseSettings } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
@ -15,10 +16,12 @@ export const ParamNoiseToggle = () => {
dispatch(setShouldUseNoiseSettings(e.target.checked)); dispatch(setShouldUseNoiseSettings(e.target.checked));
return ( return (
<IAISwitch <NoiseEnablePopover>
label="Enable Noise Settings" <IAISwitch
isChecked={shouldUseNoiseSettings} label="Enable Noise Settings"
onChange={handleChange} isChecked={shouldUseNoiseSettings}
/> onChange={handleChange}
/>
</NoiseEnablePopover>
); );
}; };

View File

@ -3,14 +3,17 @@ import { memo } from 'react';
import ParamSeed from './ParamSeed'; import ParamSeed from './ParamSeed';
import ParamSeedShuffle from './ParamSeedShuffle'; import ParamSeedShuffle from './ParamSeedShuffle';
import ParamSeedRandomize from './ParamSeedRandomize'; import ParamSeedRandomize from './ParamSeedRandomize';
import { ParamSeedPopover } from 'features/informationalPopovers/components/paramSeed';
const ParamSeedFull = () => { const ParamSeedFull = () => {
return ( return (
<Flex sx={{ gap: 3, alignItems: 'flex-end' }}> <ParamSeedPopover>
<ParamSeed /> <Flex sx={{ gap: 3, alignItems: 'flex-end' }}>
<ParamSeedShuffle /> <ParamSeed />
<ParamSeedRandomize /> <ParamSeedShuffle />
</Flex> <ParamSeedRandomize />
</Flex>
</ParamSeedPopover>
); );
}; };

View File

@ -15,6 +15,7 @@ import IAIMantineSelectItemWithTooltip from 'common/components/IAIMantineSelectI
import { vaeSelected } from 'features/parameters/store/generationSlice'; import { vaeSelected } from 'features/parameters/store/generationSlice';
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants'; import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToVAEModelParam } from 'features/parameters/util/modelIdToVAEModelParam'; import { modelIdToVAEModelParam } from 'features/parameters/util/modelIdToVAEModelParam';
import { ParamVAEPopover } from 'features/informationalPopovers/components/paramVAE';
const selector = createSelector( const selector = createSelector(
stateSelector, stateSelector,
@ -93,17 +94,19 @@ const ParamVAEModelSelect = () => {
); );
return ( return (
<IAIMantineSearchableSelect <ParamVAEPopover>
itemComponent={IAIMantineSelectItemWithTooltip} <IAIMantineSearchableSelect
tooltip={selectedVaeModel?.description} itemComponent={IAIMantineSelectItemWithTooltip}
label={t('modelManager.vae')} tooltip={selectedVaeModel?.description}
value={selectedVaeModel?.id ?? 'default'} label={t('modelManager.vae')}
placeholder="Default" value={selectedVaeModel?.id ?? 'default'}
data={data} placeholder="Default"
onChange={handleChangeModel} data={data}
disabled={data.length === 0} onChange={handleChangeModel}
clearable disabled={data.length === 0}
/> clearable
/>
</ParamVAEPopover>
); );
}; };

View File

@ -3,6 +3,7 @@ import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { ParamVAEPrecisionPopover } from 'features/informationalPopovers/components/paramVAEPrecision';
import { vaePrecisionChanged } from 'features/parameters/store/generationSlice'; import { vaePrecisionChanged } from 'features/parameters/store/generationSlice';
import { PrecisionParam } from 'features/parameters/types/parameterSchemas'; import { PrecisionParam } from 'features/parameters/types/parameterSchemas';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
@ -34,12 +35,14 @@ const ParamVAEModelSelect = () => {
); );
return ( return (
<IAIMantineSelect <ParamVAEPrecisionPopover>
label="VAE Precision" <IAIMantineSelect
value={vaePrecision} label="VAE Precision"
data={DATA} value={vaePrecision}
onChange={handleChange} data={DATA}
/> onChange={handleChange}
/>
</ParamVAEPrecisionPopover>
); );
}; };

View File

@ -7,6 +7,7 @@ import SubParametersWrapper from 'features/parameters/components/Parameters/SubP
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { setSDXLImg2ImgDenoisingStrength } from '../store/sdxlSlice'; import { setSDXLImg2ImgDenoisingStrength } from '../store/sdxlSlice';
import { ParamDenoisingStrengthPopover } from 'features/informationalPopovers/components/paramDenoisingStrength';
const selector = createSelector( const selector = createSelector(
[stateSelector], [stateSelector],
@ -36,19 +37,21 @@ const ParamSDXLImg2ImgDenoisingStrength = () => {
return ( return (
<SubParametersWrapper> <SubParametersWrapper>
<IAISlider <ParamDenoisingStrengthPopover>
label={`${t('parameters.denoisingStrength')}`} <IAISlider
step={0.01} label={`${t('parameters.denoisingStrength')}`}
min={0} step={0.01}
max={1} min={0}
onChange={handleChange} max={1}
handleReset={handleReset} onChange={handleChange}
value={sdxlImg2ImgDenoisingStrength} handleReset={handleReset}
isInteger={false} value={sdxlImg2ImgDenoisingStrength}
withInput isInteger={false}
withSliderMarks withInput
withReset withSliderMarks
/> withReset
/>
</ParamDenoisingStrengthPopover>
</SubParametersWrapper> </SubParametersWrapper>
); );
}; };