feat(ui): make jump to page a popover

This commit is contained in:
Mary Hipp 2024-07-24 16:24:23 -04:00 committed by psychedelicious
parent 2a9fdc6314
commit cf1af94f53
3 changed files with 114 additions and 53 deletions

View File

@ -381,7 +381,9 @@
"featuresWillReset": "If you delete this image, those features will immediately be reset.", "featuresWillReset": "If you delete this image, those features will immediately be reset.",
"galleryImageSize": "Image Size", "galleryImageSize": "Image Size",
"gallerySettings": "Gallery Settings", "gallerySettings": "Gallery Settings",
"go": "Go",
"image": "image", "image": "image",
"jump": "Jump",
"loading": "Loading", "loading": "Loading",
"loadMore": "Load More", "loadMore": "Load More",
"newestFirst": "Newest First", "newestFirst": "Newest First",

View File

@ -1,8 +1,10 @@
import { Button, CompositeNumberInput, Flex, Icon, IconButton, Spacer } from '@invoke-ai/ui-library'; import { Button, Flex, Icon, IconButton } from '@invoke-ai/ui-library';
import { ELLIPSIS, useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination'; import { ELLIPSIS, useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { PiCaretLeftBold, PiCaretRightBold, PiDotsThreeBold } from 'react-icons/pi'; import { PiCaretLeftBold, PiCaretRightBold, PiDotsThreeBold } from 'react-icons/pi';
import { JumpTo } from './JumpTo';
export const GalleryPagination = () => { export const GalleryPagination = () => {
const { goPrev, goNext, isPrevEnabled, isNextEnabled, pageButtons, goToPage, currentPage, total } = const { goPrev, goNext, isPrevEnabled, isNextEnabled, pageButtons, goToPage, currentPage, total } =
useGalleryPagination(); useGalleryPagination();
@ -15,24 +17,14 @@ export const GalleryPagination = () => {
goNext(); goNext();
}, [goNext]); }, [goNext]);
const onChangeJumpTo = useCallback(
(v: number) => {
goToPage(v - 1);
},
[goToPage]
);
if (!total) { if (!total) {
return null; return null;
} }
return ( return (
<Flex justifyContent="space-between" alignItems="center" w="full"> <Flex justifyContent="center" alignItems="center" w="full" gap={1}>
<Spacer w="auto" />
<Flex flexGrow="1" justifyContent="center">
<Flex gap={1} alignItems="center">
<IconButton <IconButton
size="xs" size="sm"
aria-label="prev" aria-label="prev"
icon={<PiCaretLeftBold />} icon={<PiCaretLeftBold />}
onClick={onClickPrev} onClick={onClickPrev}
@ -45,7 +37,7 @@ export const GalleryPagination = () => {
} }
return ( return (
<Button <Button
size="xs" size="sm"
key={page} key={page}
onClick={goToPage.bind(null, page - 1)} onClick={goToPage.bind(null, page - 1)}
variant={currentPage === page - 1 ? 'solid' : 'outline'} variant={currentPage === page - 1 ? 'solid' : 'outline'}
@ -55,24 +47,14 @@ export const GalleryPagination = () => {
); );
})} })}
<IconButton <IconButton
size="xs" size="sm"
aria-label="next" aria-label="next"
icon={<PiCaretRightBold />} icon={<PiCaretRightBold />}
onClick={onClickNext} onClick={onClickNext}
isDisabled={!isNextEnabled} isDisabled={!isNextEnabled}
variant="ghost" variant="ghost"
/> />
</Flex> <JumpTo />
</Flex>
<CompositeNumberInput
size="xs"
maxW="60px"
value={currentPage + 1}
min={1}
max={total}
step={1}
onChange={onChangeJumpTo}
/>
</Flex> </Flex>
); );
}; };

View File

@ -0,0 +1,77 @@
import {
Button,
CompositeNumberInput,
Flex,
FormControl,
Popover,
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverTrigger,
useDisclosure,
} from '@invoke-ai/ui-library';
import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination';
import { useCallback, useEffect, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
export const JumpTo = () => {
const { t } = useTranslation();
const { goToPage, currentPage, pages } = useGalleryPagination();
const [newPage, setNewPage] = useState(currentPage);
const { isOpen, onToggle, onClose } = useDisclosure();
const onChangeJumpTo = useCallback((v: number) => {
setNewPage(v - 1);
}, []);
const onClickGo = useCallback(() => {
goToPage(newPage);
onClose();
}, [newPage, goToPage, onClose]);
useHotkeys(
'enter',
() => {
if (isOpen) {
onClickGo();
}
},
[isOpen, onClickGo]
);
useEffect(() => {
setNewPage(currentPage);
}, [currentPage]);
return (
<Popover isOpen={isOpen} onClose={onClose}>
<PopoverTrigger>
<Button aria-label={t('gallery.jump')} size="xs" onClick={onToggle}>
{t('gallery.jump')}
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<Flex gap={2}>
<FormControl>
<CompositeNumberInput
size="sm"
maxW="60px"
value={newPage + 1}
min={1}
max={pages}
step={1}
onChange={onChangeJumpTo}
/>
<Button size="sm" onClick={onClickGo}>
{t('gallery.go')}
</Button>
</FormControl>
</Flex>
</PopoverBody>
</PopoverContent>
</Popover>
);
};