feat(ui): responsive wip

- Fixed a bunch of padding and margin issues across the app
- Fixed the Invoke logo compressing
- Disabled the visibility of the options panel pin button in tablet and mobile views
- Refined the header menu options in mobile and tablet views
- Refined other site header elements in mobile and tablet views
- Aligned Tab Icons to center in mobile and tablet views
This commit is contained in:
blessedcoolant 2023-04-18 00:50:09 +12:00
parent 9749ef34b5
commit b800a8eb2e
11 changed files with 68 additions and 21 deletions

View File

@ -19,7 +19,8 @@
"toggleAutoscroll": "Toggle autoscroll", "toggleAutoscroll": "Toggle autoscroll",
"toggleLogViewer": "Toggle Log Viewer", "toggleLogViewer": "Toggle Log Viewer",
"showGallery": "Show Gallery", "showGallery": "Show Gallery",
"showOptionsPanel": "Show Options Panel" "showOptionsPanel": "Show Options Panel",
"menu": "Menu"
}, },
"common": { "common": {
"hotkeysLabel": "Hotkeys", "hotkeysLabel": "Hotkeys",

View File

@ -35,7 +35,7 @@ const App = (props: PropsWithChildren) => {
<ProgressBar /> <ProgressBar />
<Grid <Grid
gap={4} gap={4}
p={{ base: 1, lg: 4 }} p={4}
gridAutoRows="min-content auto" gridAutoRows="min-content auto"
w={APP_WIDTH} w={APP_WIDTH}
h={APP_HEIGHT} h={APP_HEIGHT}

View File

@ -409,7 +409,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
flexWrap: 'wrap', flexWrap: 'wrap',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
columnGap: '0.5em', gap: 2,
}} }}
{...props} {...props}
> >

View File

@ -189,8 +189,8 @@ export default function ImageGalleryPanel() {
const imageGalleryContent = () => { const imageGalleryContent = () => {
return ( return (
<Flex w="100vw" h="100vh"> <Flex w="100vw" h="100vh" paddingRight={{ base: 8, xl: 0 }}>
<ImageGalleryContent />; <ImageGalleryContent />
</Flex> </Flex>
); );
}; };

View File

@ -10,8 +10,15 @@ const InvokeAILogoComponent = () => {
return ( return (
<Flex alignItems="center" gap={3} ps={1}> <Flex alignItems="center" gap={3} ps={1}>
<Image src={InvokeAILogoImage} alt="invoke-ai-logo" w="32px" h="32px" /> <Image
<Flex gap={3} display={{ base: 'none', sm: 'inherit' }}> src={InvokeAILogoImage}
alt="invoke-ai-logo"
w="32px"
h="32px"
minW="32px"
minH="32px"
/>
<Flex gap={3} display={{ base: 'none', md: 'inherit' }}>
<Text fontSize="xl"> <Text fontSize="xl">
invoke <strong>ai</strong> invoke <strong>ai</strong>
</Text> </Text>

View File

@ -7,6 +7,8 @@ import InvokeAILogoComponent from './InvokeAILogoComponent';
import SiteHeaderMenu from './SiteHeaderMenu'; import SiteHeaderMenu from './SiteHeaderMenu';
import useResolution from 'common/hooks/useResolution'; import useResolution from 'common/hooks/useResolution';
import { FaBars } from 'react-icons/fa'; import { FaBars } from 'react-icons/fa';
import { IAIIconButton } from 'exports';
import { useTranslation } from 'react-i18next';
/** /**
* Header, includes color mode toggle, settings button, status message. * Header, includes color mode toggle, settings button, status message.
@ -14,11 +16,13 @@ import { FaBars } from 'react-icons/fa';
const SiteHeader = () => { const SiteHeader = () => {
const [menuOpened, setMenuOpened] = useState(false); const [menuOpened, setMenuOpened] = useState(false);
const resolution = useResolution(); const resolution = useResolution();
const { t } = useTranslation();
const isMobile = ['mobile', 'tablet'].includes(resolution);
return ( return (
<Grid gridTemplateColumns="auto max-content"> <Grid
gridTemplateColumns="auto max-content"
paddingRight={{ base: 10, xl: 0 }}
>
<InvokeAILogoComponent /> <InvokeAILogoComponent />
<Flex alignItems="center" gap={2}> <Flex alignItems="center" gap={2}>
@ -26,12 +30,33 @@ const SiteHeader = () => {
<ModelSelect /> <ModelSelect />
{!isMobile && <SiteHeaderMenu />} {resolution === 'desktop' ? (
<Flex> <SiteHeaderMenu />
{isMobile && <FaBars onClick={() => setMenuOpened(!menuOpened)} />} ) : (
</Flex> <IAIIconButton
icon={<FaBars />}
aria-label={t('accessibility.menu')}
background={menuOpened ? 'base.800' : 'none'}
_hover={{ background: menuOpened ? 'base.800' : 'none' }}
onClick={() => setMenuOpened(!menuOpened)}
p={0}
></IAIIconButton>
)}
</Flex> </Flex>
<Flex>{isMobile && menuOpened && <SiteHeaderMenu />}</Flex>
{resolution !== 'desktop' && menuOpened && (
<Flex
position="absolute"
right={6}
top={16}
backgroundColor="base.800"
padding={4}
borderRadius={4}
zIndex={{ base: 99, xl: 0 }}
>
<SiteHeaderMenu />
</Flex>
)}
</Grid> </Grid>
); );
}; };

View File

@ -13,7 +13,11 @@ const SiteHeaderMenu = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<> <Flex
alignItems="center"
flexDirection={{ base: 'column', xl: 'row' }}
gap={{ base: 4, xl: 1 }}
>
<ModelManagerModal> <ModelManagerModal>
<IAIIconButton <IAIIconButton
aria-label={t('modelManager.modelManager')} aria-label={t('modelManager.modelManager')}
@ -101,7 +105,7 @@ const SiteHeaderMenu = () => {
icon={<MdSettings />} icon={<MdSettings />}
/> />
</SettingsModal> </SettingsModal>
</> </Flex>
); );
}; };

View File

@ -1,5 +1,6 @@
import { import {
ChakraProps, ChakraProps,
Flex,
Icon, Icon,
Tab, Tab,
TabList, TabList,
@ -177,7 +178,12 @@ export default function InvokeTabs() {
flexDir={{ base: 'column', xl: 'row' }} flexDir={{ base: 'column', xl: 'row' }}
gap={{ base: 4 }} gap={{ base: 4 }}
> >
<TabList flexDir={{ base: 'row', xl: 'column' }}>{tabs}</TabList> <TabList
flexDir={{ base: 'row', xl: 'column' }}
justifyContent={{ base: 'center', xl: 'start' }}
>
{tabs}
</TabList>
<TabPanels>{tabPanels}</TabPanels> <TabPanels>{tabPanels}</TabPanels>
</Tabs> </Tabs>
); );

View File

@ -1,4 +1,4 @@
import { Box, BoxProps, Flex, Grid, GridItem } from '@chakra-ui/react'; import { Box, BoxProps, Grid, GridItem } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { setInitialImage } from 'features/parameters/store/generationSlice'; import { setInitialImage } from 'features/parameters/store/generationSlice';
@ -65,6 +65,7 @@ const InvokeWorkarea = (props: InvokeWorkareaProps) => {
pos="relative" pos="relative"
w="full" w="full"
h={APP_CONTENT_HEIGHT} h={APP_CONTENT_HEIGHT}
minH={{ base: 1000, xl: 'auto' }}
gap={4} gap={4}
> >
<ParametersPanel>{parametersPanelContent}</ParametersPanel> <ParametersPanel>{parametersPanelContent}</ParametersPanel>
@ -72,6 +73,7 @@ const InvokeWorkarea = (props: InvokeWorkareaProps) => {
<Box <Box
pos="relative" pos="relative"
w={{ base: '100vw', xl: 'full' }} w={{ base: '100vw', xl: 'full' }}
paddingRight={{ base: 8, xl: 0 }}
h="100%" h="100%"
onDrop={handleDrop} onDrop={handleDrop}
> >

View File

@ -99,6 +99,7 @@ const ParametersPanel = ({ children }: ParametersPanelProps) => {
position="relative" position="relative"
h="full" h="full"
w={{ sm: 'full', lg: '100vw', xl: 'full' }} w={{ sm: 'full', lg: '100vw', xl: 'full' }}
paddingRight={{ base: 8, xl: 0 }}
> >
{!shouldPinParametersPanel && ( {!shouldPinParametersPanel && (
<Flex <Flex
@ -108,11 +109,11 @@ const ParametersPanel = ({ children }: ParametersPanelProps) => {
alignItems="center" alignItems="center"
> >
<InvokeAILogoComponent /> <InvokeAILogoComponent />
<PinParametersPanelButton /> {resolution == 'desktop' && <PinParametersPanelButton />}
</Flex> </Flex>
)} )}
<Scrollable>{children}</Scrollable> <Scrollable>{children}</Scrollable>
{shouldPinParametersPanel && ( {shouldPinParametersPanel && resolution == 'desktop' && (
<PinParametersPanelButton <PinParametersPanelButton
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }} sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
/> />

View File

@ -33,6 +33,7 @@ const PinParametersPanelButton = (props: PinParametersPanelButtonProps) => {
icon={shouldPinParametersPanel ? <BsPinAngleFill /> : <BsPinAngle />} icon={shouldPinParametersPanel ? <BsPinAngleFill /> : <BsPinAngle />}
variant="ghost" variant="ghost"
size="sm" size="sm"
px={{ base: 10, xl: 0 }}
sx={{ sx={{
color: 'base.700', color: 'base.700',
_hover: { _hover: {