Add go back and forward buttons and button tooltips

This commit is contained in:
chrox
2024-11-21 15:49:59 +01:00
parent e6e960d2b6
commit df845ae33b
7 changed files with 119 additions and 30 deletions
@@ -6,6 +6,7 @@ import { useReaderStore } from '@/store/readerStore';
import { useEnv } from '@/context/EnvContext';
import { BookNote } from '@/types/book';
import { uniqueId } from '@/utils/misc';
import Button from '@/components/Button';
interface BookmarkTogglerProps {
bookKey: string;
@@ -76,13 +77,18 @@ const BookmarkToggler: React.FC<BookmarkTogglerProps> = ({ bookKey }) => {
}, [config, progress]);
return (
<button onClick={toggleBookmark} className='p-2'>
{isBookmarked ? (
<MdOutlineBookmark size={20} className='text-base-content' />
) : (
<MdOutlineBookmarkAdd size={20} className='text-base-content' />
)}
</button>
<Button
icon={
isBookmarked ? (
<MdOutlineBookmark size={20} className='text-base-content' />
) : (
<MdOutlineBookmarkAdd size={20} className='text-base-content' />
)
}
onClick={toggleBookmark}
tooltip='Bookmark'
tooltipDirection='bottom'
></Button>
);
};
@@ -30,6 +30,13 @@ export interface FoliateView extends HTMLElement {
clearSearch: () => void;
select: (target: string | number | { fraction: number }) => void;
deselect: () => void;
history: {
canGoBack: boolean;
canGoForward: boolean;
back: () => void;
forward: () => void;
clear: () => void;
};
renderer: {
setStyles?: (css: string) => void;
setAttribute: (name: string, value: string | number) => void;
@@ -1,8 +1,10 @@
import React from 'react';
import clsx from 'clsx';
import { RiArrowLeftWideLine, RiArrowRightWideLine } from 'react-icons/ri';
import { RiArrowGoBackLine, RiArrowGoForwardLine } from 'react-icons/ri';
import { useReaderStore } from '@/store/readerStore';
import Button from '@/components/Button';
interface FooterBarProps {
bookKey: string;
@@ -12,19 +14,29 @@ interface FooterBarProps {
const FooterBar: React.FC<FooterBarProps> = ({ bookKey, pageinfo, isHoveredAnim }) => {
const { isSideBarVisible, hoveredBookKey, setHoveredBookKey, getView } = useReaderStore();
const view = getView(bookKey);
const handleProgressChange = (event: React.ChangeEvent) => {
const newProgress = parseInt((event.target as HTMLInputElement).value, 10);
getView(bookKey)?.goToFraction(newProgress / 100.0);
view?.goToFraction(newProgress / 100.0);
};
const handleGoPrev = () => {
getView(bookKey)?.goLeft();
view?.goLeft();
};
const handleGoNext = () => {
getView(bookKey)?.goRight();
view?.goRight();
};
const handleGoBack = () => {
view?.history.back();
};
const handleGoForward = () => {
view?.history.forward();
};
const pageinfoValid = pageinfo && pageinfo.total > 0 && pageinfo.current >= 0;
const progressFraction = pageinfoValid ? pageinfo.current / pageinfo.total : 0;
return (
@@ -39,9 +51,19 @@ const FooterBar: React.FC<FooterBarProps> = ({ bookKey, pageinfo, isHoveredAnim
onMouseEnter={() => setHoveredBookKey(bookKey)}
onMouseLeave={() => setHoveredBookKey('')}
>
<button className='btn btn-ghost mx-2 h-8 min-h-8 w-8 p-0' onClick={handleGoPrev}>
<RiArrowLeftWideLine size={20} />
</button>
<Button icon={<RiArrowLeftWideLine size={20} />} onClick={handleGoPrev} tooltip='Go Left' />
<Button
icon={<RiArrowGoBackLine size={20} />}
onClick={handleGoBack}
tooltip='Go Back'
disabled={!view?.history.canGoBack}
/>
<Button
icon={<RiArrowGoForwardLine size={20} />}
onClick={handleGoForward}
tooltip='Go Forward'
disabled={!view?.history.canGoForward}
/>
<span className='mx-2 text-center text-sm'>
{pageinfoValid ? `${Math.round(progressFraction * 100)}%` : ''}
</span>
@@ -53,9 +75,7 @@ const FooterBar: React.FC<FooterBarProps> = ({ bookKey, pageinfo, isHoveredAnim
value={pageinfoValid ? progressFraction * 100 : 0}
onChange={(e) => handleProgressChange(e)}
/>
<button className='btn btn-ghost mx-2 h-8 min-h-8 w-8 p-0' onClick={handleGoNext}>
<RiArrowRightWideLine size={20} />
</button>
<Button icon={<RiArrowRightWideLine size={20} />} onClick={handleGoNext} tooltip='Go Right' />
</div>
);
};
@@ -2,6 +2,7 @@ import React from 'react';
import { TbLayoutSidebarRight, TbLayoutSidebarRightFilled } from 'react-icons/tb';
import { useReaderStore } from '@/store/readerStore';
import Button from '@/components/Button';
interface NotebookTogglerProps {
bookKey: string;
@@ -18,13 +19,18 @@ const NotebookToggler: React.FC<NotebookTogglerProps> = ({ bookKey }) => {
}
};
return (
<button onClick={handleToggleSidebar} className='p-2'>
{sideBarBookKey == bookKey && isNotebookVisible ? (
<TbLayoutSidebarRightFilled size={20} className='text-base-content' />
) : (
<TbLayoutSidebarRight size={20} className='text-base-content' />
)}
</button>
<Button
icon={
sideBarBookKey == bookKey && isNotebookVisible ? (
<TbLayoutSidebarRightFilled size={20} className='text-base-content' />
) : (
<TbLayoutSidebarRight size={20} className='text-base-content' />
)
}
onClick={handleToggleSidebar}
tooltip='Notebook'
tooltipDirection='bottom'
></Button>
);
};
@@ -2,6 +2,7 @@ import React from 'react';
import { TbLayoutSidebar, TbLayoutSidebarFilled } from 'react-icons/tb';
import { useReaderStore } from '@/store/readerStore';
import Button from '@/components/Button';
interface SidebarTogglerProps {
bookKey: string;
@@ -18,13 +19,18 @@ const SidebarToggler: React.FC<SidebarTogglerProps> = ({ bookKey }) => {
}
};
return (
<button onClick={handleToggleSidebar} className='p-2'>
{sideBarBookKey == bookKey && isSideBarVisible ? (
<TbLayoutSidebarFilled size={20} className='text-base-content' />
) : (
<TbLayoutSidebar size={20} className='text-base-content' />
)}
</button>
<Button
icon={
sideBarBookKey === bookKey && isSideBarVisible ? (
<TbLayoutSidebarFilled size={20} className='text-base-content' />
) : (
<TbLayoutSidebar size={20} className='text-base-content' />
)
}
onClick={handleToggleSidebar}
tooltip='Sidebar'
tooltipDirection='bottom'
/>
);
};
@@ -0,0 +1,43 @@
import React from 'react';
import clsx from 'clsx';
interface ButtonProps {
icon: React.ReactNode;
onClick: () => void;
disabled?: boolean;
tooltip?: string;
tooltipDirection?: 'top' | 'bottom' | 'left' | 'right';
className?: string;
}
const Button: React.FC<ButtonProps> = ({
icon,
onClick,
disabled = false,
tooltip,
tooltipDirection = 'top',
className,
}) => {
return (
<div
className={clsx('tooltip z-50', tooltip && `tooltip-${tooltipDirection}`, {
'tooltip-hidden': !tooltip,
})}
data-tip={tooltip}
>
<button
className={clsx(
'btn btn-ghost mx-2 h-8 min-h-8 w-8 p-0',
disabled && 'btn-disabled !bg-transparent',
className,
)}
onClick={disabled ? undefined : onClick}
disabled={disabled}
>
{icon}
</button>
</div>
);
};
export default Button;
+1
View File
@@ -13,6 +13,7 @@ const config: Config = {
{ pattern: /text-./ },
{ pattern: /fill-./ },
{ pattern: /decoration-./ },
{ pattern: /tooltip-./ },
],
theme: {
extend: {