forked from akai/readest
ui: style tweaks on Popup and Dialog (#448)
This commit is contained in:
@@ -76,7 +76,7 @@ const FootnotePopup: React.FC<FootnotePopupProps> = ({ bookKey, bookDoc }) => {
|
||||
if (!gridFrame) return;
|
||||
const rect = gridFrame.getBoundingClientRect();
|
||||
const viewSettings = getViewSettings(bookKey)!;
|
||||
const triangPos = getPosition(detail.a, rect, viewSettings.vertical);
|
||||
const triangPos = getPosition(detail.a, rect, popupPadding, viewSettings.vertical);
|
||||
const popupPos = getPopupPosition(
|
||||
triangPos,
|
||||
rect,
|
||||
@@ -113,7 +113,7 @@ const FootnotePopup: React.FC<FootnotePopupProps> = ({ bookKey, bookDoc }) => {
|
||||
if (!gridFrame) return;
|
||||
const rect = gridFrame.getBoundingClientRect();
|
||||
const viewSettings = getViewSettings(bookKey)!;
|
||||
const triangPos = getPosition(element, rect, viewSettings.vertical);
|
||||
const triangPos = getPosition(element, rect, popupPadding, viewSettings.vertical);
|
||||
const popupPos = getPopupPosition(
|
||||
triangPos,
|
||||
rect,
|
||||
|
||||
@@ -250,7 +250,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
const gridFrame = document.querySelector(`#gridcell-${bookKey}`);
|
||||
if (!gridFrame) return;
|
||||
const rect = gridFrame.getBoundingClientRect();
|
||||
const triangPos = getPosition(selection.range, rect, viewSettings.vertical);
|
||||
const triangPos = getPosition(selection.range, rect, popupPadding, viewSettings.vertical);
|
||||
const annotPopupPos = getPopupPosition(
|
||||
triangPos,
|
||||
rect,
|
||||
|
||||
@@ -108,18 +108,20 @@ const WikipediaPopup: React.FC<WikipediaPopupProps> = ({
|
||||
height={popupHeight}
|
||||
position={position}
|
||||
trianglePosition={trianglePosition}
|
||||
className='select-text overflow-y-auto'
|
||||
className='select-text'
|
||||
>
|
||||
<main className='p-2 font-sans'></main>
|
||||
<footer className='hidden data-[state=loaded]:block data-[state=error]:hidden data-[state=loading]:hidden'>
|
||||
<div className='p-4 text-sm opacity-60'>
|
||||
From <a id='link'>Wikipedia</a>, released under the{' '}
|
||||
<a href='https://en.wikipedia.org/wiki/Wikipedia:Text_of_the_Creative_Commons_Attribution-ShareAlike_4.0_International_License'>
|
||||
CC BY-SA License
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
</footer>
|
||||
<div className='text-base-content flex h-full flex-col pt-2'>
|
||||
<main className='flex-grow overflow-y-auto px-2 font-sans'></main>
|
||||
<footer className='mt-auto hidden data-[state=loaded]:block data-[state=error]:hidden data-[state=loading]:hidden'>
|
||||
<div className='flex items-center px-4 py-2 text-sm opacity-60'>
|
||||
From <a id='link'>Wikipedia</a>, released under the{' '}
|
||||
<a href='https://en.wikipedia.org/wiki/Wikipedia:Text_of_the_Creative_Commons_Attribution-ShareAlike_4.0_International_License'>
|
||||
CC BY-SA License
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</Popup>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -163,15 +163,17 @@ const WiktionaryPopup: React.FC<WiktionaryPopupProps> = ({
|
||||
width={popupWidth}
|
||||
height={popupHeight}
|
||||
position={position}
|
||||
className='select-text overflow-y-auto'
|
||||
className='select-text'
|
||||
>
|
||||
<main className='p-4 font-sans' />
|
||||
<footer className='hidden data-[state=loaded]:block data-[state=error]:hidden data-[state=loading]:hidden'>
|
||||
<div className='p-4 text-sm opacity-60'>
|
||||
From <a id='link'>Wiktionary</a>, released under the{' '}
|
||||
<a href='https://creativecommons.org/licenses/by-sa/4.0/'>CC BY-SA License</a>.
|
||||
</div>
|
||||
</footer>
|
||||
<div className='flex h-full flex-col'>
|
||||
<main className='flex-grow overflow-y-auto p-4 font-sans' />
|
||||
<footer className='mt-auto hidden data-[state=loaded]:block data-[state=error]:hidden data-[state=loading]:hidden'>
|
||||
<div className='flex items-center px-4 py-2 text-sm opacity-60'>
|
||||
From <a id='link'>Wiktionary</a>, released under the{' '}
|
||||
<a href='https://creativecommons.org/licenses/by-sa/4.0/'>CC BY-SA License</a>.
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</Popup>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -82,7 +82,7 @@ const BookDetailModal = ({ book, isOpen, onClose }: BookDetailModalProps) => {
|
||||
title={_('Book Details')}
|
||||
isOpen={isOpen}
|
||||
onClose={handleClose}
|
||||
className='!bg-[rgba(0,0,0,0.5)]'
|
||||
bgClassName='sm:bg-black/50'
|
||||
boxClassName='sm:min-w-[480px] sm:h-auto'
|
||||
contentClassName='!px-6 !py-2'
|
||||
>
|
||||
|
||||
@@ -15,6 +15,7 @@ interface DialogProps {
|
||||
header?: ReactNode;
|
||||
title?: string;
|
||||
className?: string;
|
||||
bgClassName?: string;
|
||||
boxClassName?: string;
|
||||
contentClassName?: string;
|
||||
onClose: () => void;
|
||||
@@ -27,6 +28,7 @@ const Dialog: React.FC<DialogProps> = ({
|
||||
header,
|
||||
title,
|
||||
className,
|
||||
bgClassName,
|
||||
boxClassName,
|
||||
contentClassName,
|
||||
onClose,
|
||||
@@ -104,7 +106,7 @@ const Dialog: React.FC<DialogProps> = ({
|
||||
open={isOpen}
|
||||
className={clsx('modal sm:min-w-90 z-50 h-full w-full !bg-transparent sm:w-full', className)}
|
||||
>
|
||||
<div className='overlay fixed inset-0 z-10 bg-black/50 sm:bg-black/20' />
|
||||
<div className={clsx('overlay fixed inset-0 z-10 bg-black/50 sm:bg-black/20', bgClassName)} />
|
||||
<div
|
||||
className={clsx(
|
||||
'modal-box settings-content z-20 flex flex-col rounded-none rounded-tl-2xl rounded-tr-2xl p-0 sm:rounded-2xl',
|
||||
|
||||
@@ -64,7 +64,19 @@ const getIframeElement = (nodeElement: Range | Element): HTMLIFrameElement | nul
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getPosition = (target: Range | Element, rect: Rect, isVertical: boolean = false) => {
|
||||
const constrainPointWithinRect = (point: Point, rect: Rect, padding: number) => {
|
||||
return {
|
||||
x: Math.max(padding, Math.min(point.x, rect.right - padding)),
|
||||
y: Math.max(padding, Math.min(point.y, rect.bottom - padding)),
|
||||
};
|
||||
};
|
||||
|
||||
export const getPosition = (
|
||||
target: Range | Element,
|
||||
rect: Rect,
|
||||
paddingPx: number,
|
||||
isVertical: boolean = false,
|
||||
) => {
|
||||
const frameElement = getIframeElement(target);
|
||||
const transform = frameElement ? getComputedStyle(frameElement).transform : '';
|
||||
const match = transform.match(/matrix\((.+)\)/);
|
||||
@@ -80,10 +92,14 @@ export const getPosition = (target: Range | Element, rect: Rect, isVertical: boo
|
||||
const rightSpace = rect.right - first.right;
|
||||
const dir = leftSpace > rightSpace ? 'left' : 'right';
|
||||
const position = {
|
||||
point: {
|
||||
x: dir === 'left' ? first.left - rect.left - 6 : first.right - rect.left + 6,
|
||||
y: (first.top + first.bottom) / 2 - rect.top,
|
||||
},
|
||||
point: constrainPointWithinRect(
|
||||
{
|
||||
x: dir === 'left' ? first.left - rect.left - 6 : first.right - rect.left + 6,
|
||||
y: (first.top + first.bottom) / 2 - rect.top,
|
||||
},
|
||||
rect,
|
||||
paddingPx,
|
||||
),
|
||||
dir,
|
||||
} as Position;
|
||||
const inView = pointIsInView(position.point);
|
||||
@@ -119,12 +135,12 @@ export const getPopupPosition = (
|
||||
popupPoint.y = position.point.y - popupHeightPx;
|
||||
} else if (position.dir === 'down') {
|
||||
popupPoint.x = position.point.x - popupWidthPx / 2;
|
||||
popupPoint.y = position.point.y + 5;
|
||||
popupPoint.y = position.point.y + 6;
|
||||
} else if (position.dir === 'left') {
|
||||
popupPoint.x = position.point.x - popupWidthPx;
|
||||
popupPoint.y = position.point.y - popupHeightPx / 2;
|
||||
} else if (position.dir === 'right') {
|
||||
popupPoint.x = position.point.x + 5;
|
||||
popupPoint.x = position.point.x + 6;
|
||||
popupPoint.y = position.point.y - popupHeightPx / 2;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user