mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): migrate to @invoke-ai/ui
This commit is contained in:
@ -1,7 +1,5 @@
|
||||
import { useDisclosure } from '@chakra-ui/react';
|
||||
import { Button, ConfirmationAlertDialog, useDisclosure } from '@invoke-ai/ui';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||
import { clearCanvasHistory } from 'features/canvas/store/canvasSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
@ -20,15 +18,15 @@ const ClearCanvasHistoryButtonModal = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<InvButton
|
||||
<Button
|
||||
onClick={onOpen}
|
||||
size="sm"
|
||||
leftIcon={<PiTrashSimpleFill />}
|
||||
isDisabled={isStaging}
|
||||
>
|
||||
{t('unifiedCanvas.clearCanvasHistory')}
|
||||
</InvButton>
|
||||
<InvConfirmationAlertDialog
|
||||
</Button>
|
||||
<ConfirmationAlertDialog
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
title={t('unifiedCanvas.clearCanvasHistory')}
|
||||
@ -38,7 +36,7 @@ const ClearCanvasHistoryButtonModal = () => {
|
||||
<p>{t('unifiedCanvas.clearCanvasHistoryMessage')}</p>
|
||||
<br />
|
||||
<p>{t('unifiedCanvas.clearCanvasHistoryConfirm')}</p>
|
||||
</InvConfirmationAlertDialog>
|
||||
</ConfirmationAlertDialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, chakra, Flex } from '@chakra-ui/react';
|
||||
import { Box, chakra, Flex } from '@invoke-ai/ui';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
|
@ -1,11 +1,11 @@
|
||||
// Grid drawing adapted from https://longviewcoder.com/2021/12/08/konva-a-better-grid/
|
||||
import { getArbitraryBaseColor } from '@invoke-ai/ui';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||
import type { ReactElement } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { Group, Line as KonvaLine } from 'react-konva';
|
||||
import { getArbitraryBaseColor } from 'theme/colors';
|
||||
|
||||
const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
|
||||
return {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useToken } from '@chakra-ui/react';
|
||||
import { useToken } from '@invoke-ai/ui';
|
||||
import type { CanvasImage } from 'features/canvas/store/canvasTypes';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { Button, ButtonGroup, Flex, IconButton } from '@invoke-ai/ui';
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||
import { stagingAreaImageSaved } from 'features/canvas/store/actions';
|
||||
import {
|
||||
commitStagingAreaImage,
|
||||
@ -14,7 +12,6 @@ import {
|
||||
setShouldShowStagingImage,
|
||||
setShouldShowStagingOutline,
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { InvIconButton } from 'index';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -136,8 +133,8 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
onMouseEnter={handleMouseOver}
|
||||
onMouseLeave={handleMouseOut}
|
||||
>
|
||||
<InvButtonGroup borderRadius="base" shadow="dark-lg">
|
||||
<InvIconButton
|
||||
<ButtonGroup borderRadius="base" shadow="dark-lg">
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.previous')} (Left)`}
|
||||
aria-label={`${t('unifiedCanvas.previous')} (Left)`}
|
||||
icon={<PiArrowLeftBold />}
|
||||
@ -145,13 +142,13 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
colorScheme="invokeBlue"
|
||||
isDisabled={!shouldShowStagingImage}
|
||||
/>
|
||||
<InvButton
|
||||
<Button
|
||||
colorScheme="base"
|
||||
pointerEvents="none"
|
||||
isDisabled={!shouldShowStagingImage}
|
||||
minW={20}
|
||||
>{`${currentIndex + 1}/${total}`}</InvButton>
|
||||
<InvIconButton
|
||||
>{`${currentIndex + 1}/${total}`}</Button>
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.next')} (Right)`}
|
||||
aria-label={`${t('unifiedCanvas.next')} (Right)`}
|
||||
icon={<PiArrowRightBold />}
|
||||
@ -159,16 +156,16 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
colorScheme="invokeBlue"
|
||||
isDisabled={!shouldShowStagingImage}
|
||||
/>
|
||||
</InvButtonGroup>
|
||||
<InvButtonGroup borderRadius="base" shadow="dark-lg">
|
||||
<InvIconButton
|
||||
</ButtonGroup>
|
||||
<ButtonGroup borderRadius="base" shadow="dark-lg">
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.accept')} (Enter)`}
|
||||
aria-label={`${t('unifiedCanvas.accept')} (Enter)`}
|
||||
icon={<PiCheckBold />}
|
||||
onClick={handleAccept}
|
||||
colorScheme="invokeBlue"
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
tooltip={
|
||||
shouldShowStagingImage
|
||||
? t('unifiedCanvas.showResultsOn')
|
||||
@ -184,7 +181,7 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
onClick={handleToggleShouldShowStagingImage}
|
||||
colorScheme="invokeBlue"
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
tooltip={t('unifiedCanvas.saveToGallery')}
|
||||
aria-label={t('unifiedCanvas.saveToGallery')}
|
||||
isDisabled={!imageDTO || !imageDTO.is_intermediate}
|
||||
@ -192,7 +189,7 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
onClick={handleSaveToGallery}
|
||||
colorScheme="invokeBlue"
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
tooltip={t('unifiedCanvas.discardAll')}
|
||||
aria-label={t('unifiedCanvas.discardAll')}
|
||||
icon={<PiXBold />}
|
||||
@ -200,7 +197,7 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
colorScheme="error"
|
||||
fontSize={20}
|
||||
/>
|
||||
</InvButtonGroup>
|
||||
</ButtonGroup>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { Box, Flex } from '@invoke-ai/ui';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||
@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusTextCursorPos';
|
||||
|
||||
const warningColor = 'var(--invokeai-colors-warning-500)';
|
||||
const warningColor = 'var(--invoke-colors-warning-500)';
|
||||
|
||||
const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
|
||||
const {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { Box } from '@invoke-ai/ui';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { $cursorPosition } from 'features/canvas/store/canvasNanostore';
|
||||
import roundToHundreth from 'features/canvas/util/roundToHundreth';
|
||||
|
@ -1,16 +1,18 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Checkbox,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
IconButton,
|
||||
Popover,
|
||||
PopoverBody,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@invoke-ai/ui';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||
import { InvCheckbox } from 'common/components/InvCheckbox/wrapper';
|
||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||
import {
|
||||
InvPopover,
|
||||
InvPopoverBody,
|
||||
InvPopoverContent,
|
||||
InvPopoverTrigger,
|
||||
} from 'common/components/InvPopover/wrapper';
|
||||
import { canvasMaskSavedToGallery } from 'features/canvas/store/actions';
|
||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||
import {
|
||||
@ -109,55 +111,57 @@ const IAICanvasMaskOptions = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<InvPopover isLazy>
|
||||
<InvPopoverTrigger>
|
||||
<InvIconButton
|
||||
<Popover isLazy>
|
||||
<PopoverTrigger>
|
||||
<IconButton
|
||||
aria-label={t('unifiedCanvas.maskingOptions')}
|
||||
tooltip={t('unifiedCanvas.maskingOptions')}
|
||||
icon={<PiExcludeBold />}
|
||||
isChecked={layer === 'mask'}
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
</InvPopoverTrigger>
|
||||
<InvPopoverContent>
|
||||
<InvPopoverBody>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<PopoverBody>
|
||||
<Flex direction="column" gap={2}>
|
||||
<InvControl label={`${t('unifiedCanvas.enableMask')} (H)`}>
|
||||
<InvCheckbox
|
||||
<FormControl>
|
||||
<FormLabel>{`${t('unifiedCanvas.enableMask')} (H)`}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={isMaskEnabled}
|
||||
onChange={handleToggleEnableMask}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.preserveMaskedArea')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.preserveMaskedArea')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldPreserveMaskedArea}
|
||||
onChange={handleChangePreserveMaskedArea}
|
||||
/>
|
||||
</InvControl>
|
||||
</FormControl>
|
||||
<Box pt={2} pb={2}>
|
||||
<IAIColorPicker
|
||||
color={maskColor}
|
||||
onChange={handleChangeMaskColor}
|
||||
/>
|
||||
</Box>
|
||||
<InvButton
|
||||
<Button
|
||||
size="sm"
|
||||
leftIcon={<PiFloppyDiskBackFill />}
|
||||
onClick={handleSaveMask}
|
||||
>
|
||||
{t('unifiedCanvas.saveMask')}
|
||||
</InvButton>
|
||||
<InvButton
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
leftIcon={<PiTrashSimpleFill />}
|
||||
onClick={handleClearMask}
|
||||
>
|
||||
{t('unifiedCanvas.clearMask')}
|
||||
</InvButton>
|
||||
</Button>
|
||||
</Flex>
|
||||
</InvPopoverBody>
|
||||
</InvPopoverContent>
|
||||
</InvPopover>
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { IconButton } from '@invoke-ai/ui';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||
import { redo } from 'features/canvas/store/canvasSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { memo, useCallback } from 'react';
|
||||
@ -31,7 +31,7 @@ const IAICanvasRedoButton = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.redo')} (Ctrl+Shift+Z)`}
|
||||
tooltip={`${t('unifiedCanvas.redo')} (Ctrl+Shift+Z)`}
|
||||
icon={<PiArrowClockwiseBold />}
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvCheckbox } from 'common/components/InvCheckbox/wrapper';
|
||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||
import {
|
||||
InvPopoverBody,
|
||||
InvPopoverContent,
|
||||
InvPopoverTrigger,
|
||||
} from 'common/components/InvPopover/wrapper';
|
||||
Checkbox,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
IconButton,
|
||||
Popover,
|
||||
PopoverBody,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@invoke-ai/ui';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import ClearCanvasHistoryButtonModal from 'features/canvas/components/ClearCanvasHistoryButtonModal';
|
||||
import {
|
||||
setShouldAntialias,
|
||||
@ -19,7 +22,6 @@ import {
|
||||
setShouldShowIntermediates,
|
||||
setShouldSnapToGrid,
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { InvIconButton, InvPopover } from 'index';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
@ -109,76 +111,85 @@ const IAICanvasSettingsButtonPopover = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<InvPopover>
|
||||
<InvPopoverTrigger>
|
||||
<InvIconButton
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<IconButton
|
||||
tooltip={t('unifiedCanvas.canvasSettings')}
|
||||
aria-label={t('unifiedCanvas.canvasSettings')}
|
||||
icon={<PiGearSixBold />}
|
||||
/>
|
||||
</InvPopoverTrigger>
|
||||
<InvPopoverContent>
|
||||
<InvPopoverBody>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<PopoverBody>
|
||||
<Flex direction="column" gap={2}>
|
||||
<InvControl label={t('unifiedCanvas.showIntermediates')}>
|
||||
<InvCheckbox
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.showIntermediates')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldShowIntermediates}
|
||||
onChange={handleChangeShouldShowIntermediates}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.showGrid')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.showGrid')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldShowGrid}
|
||||
onChange={handleChangeShouldShowGrid}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.snapToGrid')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.snapToGrid')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldSnapToGrid}
|
||||
onChange={handleChangeShouldSnapToGrid}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.darkenOutsideSelection')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.darkenOutsideSelection')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldDarkenOutsideBoundingBox}
|
||||
onChange={handleChangeShouldDarkenOutsideBoundingBox}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.autoSaveToGallery')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.autoSaveToGallery')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldAutoSave}
|
||||
onChange={handleChangeShouldAutoSave}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.saveBoxRegionOnly')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.saveBoxRegionOnly')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldCropToBoundingBoxOnSave}
|
||||
onChange={handleChangeShouldCropToBoundingBoxOnSave}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.limitStrokesToBox')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.limitStrokesToBox')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldRestrictStrokesToBox}
|
||||
onChange={handleChangeShouldRestrictStrokesToBox}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.showCanvasDebugInfo')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.showCanvasDebugInfo')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldShowCanvasDebugInfo}
|
||||
onChange={handleChangeShouldShowCanvasDebugInfo}
|
||||
/>
|
||||
</InvControl>
|
||||
<InvControl label={t('unifiedCanvas.antialiasing')}>
|
||||
<InvCheckbox
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.antialiasing')}</FormLabel>
|
||||
<Checkbox
|
||||
isChecked={shouldAntialias}
|
||||
onChange={handleChangeShouldAntialias}
|
||||
/>
|
||||
</InvControl>
|
||||
</FormControl>
|
||||
<ClearCanvasHistoryButtonModal />
|
||||
</Flex>
|
||||
</InvPopoverBody>
|
||||
</InvPopoverContent>
|
||||
</InvPopover>
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,16 +1,20 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
ButtonGroup,
|
||||
CompositeNumberInput,
|
||||
CompositeSlider,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
IconButton,
|
||||
Popover,
|
||||
PopoverBody,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@invoke-ai/ui';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||
import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput';
|
||||
import {
|
||||
InvPopoverBody,
|
||||
InvPopoverContent,
|
||||
InvPopoverTrigger,
|
||||
} from 'common/components/InvPopover/wrapper';
|
||||
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
||||
import {
|
||||
$tool,
|
||||
resetToolInteractionState,
|
||||
@ -22,7 +26,6 @@ import {
|
||||
setBrushColor,
|
||||
setBrushSize,
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { InvIconButton, InvPopover } from 'index';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { memo, useCallback } from 'react';
|
||||
import type { RgbaColor } from 'react-colorful';
|
||||
@ -199,8 +202,8 @@ const IAICanvasToolChooserOptions = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<InvButtonGroup>
|
||||
<InvIconButton
|
||||
<ButtonGroup>
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.brush')} (B)`}
|
||||
tooltip={`${t('unifiedCanvas.brush')} (B)`}
|
||||
icon={<PiPaintBrushBold />}
|
||||
@ -208,7 +211,7 @@ const IAICanvasToolChooserOptions = () => {
|
||||
onClick={handleSelectBrushTool}
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.eraser')} (E)`}
|
||||
tooltip={`${t('unifiedCanvas.eraser')} (E)`}
|
||||
icon={<PiEraserBold />}
|
||||
@ -216,21 +219,21 @@ const IAICanvasToolChooserOptions = () => {
|
||||
isDisabled={isStaging}
|
||||
onClick={handleSelectEraserTool}
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.fillBoundingBox')} (Shift+F)`}
|
||||
tooltip={`${t('unifiedCanvas.fillBoundingBox')} (Shift+F)`}
|
||||
icon={<PiPaintBucketBold />}
|
||||
isDisabled={isStaging}
|
||||
onClick={handleFillRect}
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.eraseBoundingBox')} (Del/Backspace)`}
|
||||
tooltip={`${t('unifiedCanvas.eraseBoundingBox')} (Del/Backspace)`}
|
||||
icon={<PiXBold />}
|
||||
isDisabled={isStaging}
|
||||
onClick={handleEraseBoundingBox}
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.colorPicker')} (C)`}
|
||||
tooltip={`${t('unifiedCanvas.colorPicker')} (C)`}
|
||||
icon={<PiEyedropperBold />}
|
||||
@ -238,20 +241,21 @@ const IAICanvasToolChooserOptions = () => {
|
||||
isDisabled={isStaging}
|
||||
onClick={handleSelectColorPickerTool}
|
||||
/>
|
||||
<InvPopover>
|
||||
<InvPopoverTrigger>
|
||||
<InvIconButton
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<IconButton
|
||||
aria-label={t('unifiedCanvas.brushOptions')}
|
||||
tooltip={t('unifiedCanvas.brushOptions')}
|
||||
icon={<PiSlidersHorizontalBold />}
|
||||
/>
|
||||
</InvPopoverTrigger>
|
||||
<InvPopoverContent>
|
||||
<InvPopoverBody>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<PopoverBody>
|
||||
<Flex minWidth={60} direction="column" gap={4} width="100%">
|
||||
<Flex gap={4} justifyContent="space-between">
|
||||
<InvControl label={t('unifiedCanvas.brushSize')}>
|
||||
<InvSlider
|
||||
<FormControl>
|
||||
<FormLabel>{t('unifiedCanvas.brushSize')}</FormLabel>
|
||||
<CompositeSlider
|
||||
value={brushSize}
|
||||
min={1}
|
||||
max={100}
|
||||
@ -260,7 +264,7 @@ const IAICanvasToolChooserOptions = () => {
|
||||
marks={marks}
|
||||
defaultValue={50}
|
||||
/>
|
||||
<InvNumberInput
|
||||
<CompositeNumberInput
|
||||
value={brushSize}
|
||||
min={1}
|
||||
max={500}
|
||||
@ -268,7 +272,7 @@ const IAICanvasToolChooserOptions = () => {
|
||||
onChange={handleChangeBrushSize}
|
||||
defaultValue={50}
|
||||
/>
|
||||
</InvControl>
|
||||
</FormControl>
|
||||
</Flex>
|
||||
<Box w="full" pt={2} pb={2}>
|
||||
<IAIColorPicker
|
||||
@ -278,10 +282,10 @@ const IAICanvasToolChooserOptions = () => {
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
</InvPopoverBody>
|
||||
</InvPopoverContent>
|
||||
</InvPopover>
|
||||
</InvButtonGroup>
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</ButtonGroup>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import type { ComboboxOnChange } from '@invoke-ai/ui';
|
||||
import {
|
||||
ButtonGroup,
|
||||
Combobox,
|
||||
Flex,
|
||||
FormControl,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
} from '@invoke-ai/ui';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
||||
import type { InvSelectOnChange } from 'common/components/InvSelect/types';
|
||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||
import { useCopyImageToClipboard } from 'common/hooks/useCopyImageToClipboard';
|
||||
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
|
||||
import { useSingleAndDoubleClick } from 'common/hooks/useSingleAndDoubleClick';
|
||||
@ -25,7 +28,6 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import type { CanvasLayer } from 'features/canvas/store/canvasTypes';
|
||||
import { LAYER_NAMES_DICT } from 'features/canvas/store/canvasTypes';
|
||||
import { InvIconButton } from 'index';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -188,7 +190,7 @@ const IAICanvasToolbar = () => {
|
||||
dispatch(canvasDownloadedAsImage());
|
||||
}, [dispatch]);
|
||||
|
||||
const handleChangeLayer = useCallback<InvSelectOnChange>(
|
||||
const handleChangeLayer = useCallback<ComboboxOnChange>(
|
||||
(v) => {
|
||||
if (!v) {
|
||||
return;
|
||||
@ -208,44 +210,44 @@ const IAICanvasToolbar = () => {
|
||||
|
||||
return (
|
||||
<Flex alignItems="center" gap={2} flexWrap="wrap">
|
||||
<InvTooltip label={`${t('unifiedCanvas.layer')} (Q)`}>
|
||||
<InvControl isDisabled={isStaging} w="5rem">
|
||||
<InvSelect
|
||||
<Tooltip label={`${t('unifiedCanvas.layer')} (Q)`}>
|
||||
<FormControl isDisabled={isStaging} w="5rem">
|
||||
<Combobox
|
||||
value={value}
|
||||
options={LAYER_NAMES_DICT}
|
||||
onChange={handleChangeLayer}
|
||||
/>
|
||||
</InvControl>
|
||||
</InvTooltip>
|
||||
</FormControl>
|
||||
</Tooltip>
|
||||
|
||||
<IAICanvasMaskOptions />
|
||||
<IAICanvasToolChooserOptions />
|
||||
|
||||
<InvButtonGroup>
|
||||
<InvIconButton
|
||||
<ButtonGroup>
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.move')} (V)`}
|
||||
tooltip={`${t('unifiedCanvas.move')} (V)`}
|
||||
icon={<PiHandGrabbingBold />}
|
||||
isChecked={tool === 'move' || isStaging}
|
||||
onClick={handleSelectMoveTool}
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.resetView')} (R)`}
|
||||
tooltip={`${t('unifiedCanvas.resetView')} (R)`}
|
||||
icon={<PiCrosshairSimpleBold />}
|
||||
onClick={handleClickResetCanvasView}
|
||||
/>
|
||||
</InvButtonGroup>
|
||||
</ButtonGroup>
|
||||
|
||||
<InvButtonGroup>
|
||||
<InvIconButton
|
||||
<ButtonGroup>
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.mergeVisible')} (Shift+M)`}
|
||||
tooltip={`${t('unifiedCanvas.mergeVisible')} (Shift+M)`}
|
||||
icon={<PiStackBold />}
|
||||
onClick={handleMergeVisible}
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.saveToGallery')} (Shift+S)`}
|
||||
tooltip={`${t('unifiedCanvas.saveToGallery')} (Shift+S)`}
|
||||
icon={<PiFloppyDiskBold />}
|
||||
@ -253,7 +255,7 @@ const IAICanvasToolbar = () => {
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
{isClipboardAPIAvailable && (
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.copyToClipboard')} (Cmd/Ctrl+C)`}
|
||||
tooltip={`${t('unifiedCanvas.copyToClipboard')} (Cmd/Ctrl+C)`}
|
||||
icon={<PiCopyBold />}
|
||||
@ -261,21 +263,21 @@ const IAICanvasToolbar = () => {
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
)}
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.downloadAsImage')} (Shift+D)`}
|
||||
tooltip={`${t('unifiedCanvas.downloadAsImage')} (Shift+D)`}
|
||||
icon={<PiDownloadSimpleBold />}
|
||||
onClick={handleDownloadAsImage}
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
</InvButtonGroup>
|
||||
<InvButtonGroup>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<IAICanvasUndoButton />
|
||||
<IAICanvasRedoButton />
|
||||
</InvButtonGroup>
|
||||
</ButtonGroup>
|
||||
|
||||
<InvButtonGroup>
|
||||
<InvIconButton
|
||||
<ButtonGroup>
|
||||
<IconButton
|
||||
aria-label={`${t('common.upload')}`}
|
||||
tooltip={`${t('common.upload')}`}
|
||||
icon={<PiUploadSimpleBold />}
|
||||
@ -283,7 +285,7 @@ const IAICanvasToolbar = () => {
|
||||
{...getUploadButtonProps()}
|
||||
/>
|
||||
<input {...getUploadInputProps()} />
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.clearCanvas')}`}
|
||||
tooltip={`${t('unifiedCanvas.clearCanvas')}`}
|
||||
icon={<PiTrashSimpleBold />}
|
||||
@ -291,10 +293,10 @@ const IAICanvasToolbar = () => {
|
||||
colorScheme="error"
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
</InvButtonGroup>
|
||||
<InvButtonGroup>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<IAICanvasSettingsButtonPopover />
|
||||
</InvButtonGroup>
|
||||
</ButtonGroup>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { IconButton } from '@invoke-ai/ui';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||
import { undo } from 'features/canvas/store/canvasSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { memo, useCallback } from 'react';
|
||||
@ -30,7 +30,7 @@ const IAICanvasUndoButton = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<InvIconButton
|
||||
<IconButton
|
||||
aria-label={`${t('unifiedCanvas.undo')} (Ctrl+Z)`}
|
||||
tooltip={`${t('unifiedCanvas.undo')} (Ctrl+Z)`}
|
||||
icon={<PiArrowCounterClockwiseBold />}
|
||||
|
Reference in New Issue
Block a user