UI Improvements, colors and scroll to logic

This commit is contained in:
EthanHealy01
2025-12-01 13:28:17 +00:00
parent 3df684e198
commit 354a4f6d78
6 changed files with 78 additions and 7 deletions

View File

@@ -34,9 +34,23 @@ const GetPdfInfoReportView: React.FC<GetPdfInfoReportViewProps> = ({ data }) =>
};
const anchor = idMap[data.scrollTo];
if (!anchor) return;
const el = containerRef.current?.querySelector<HTMLElement>(`#${anchor}`);
if (el) {
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
const container = containerRef.current;
const el = container?.querySelector<HTMLElement>(`#${anchor}`);
if (el && container) {
// Calculate scroll position with 4rem buffer from top
const bufferPx = parseFloat(getComputedStyle(document.documentElement).fontSize) * 4;
const elementTop = el.getBoundingClientRect().top;
const containerTop = container.getBoundingClientRect().top;
const currentScroll = container.scrollTop;
const targetScroll = currentScroll + (elementTop - containerTop) - bufferPx;
container.scrollTo({ top: Math.max(0, targetScroll), behavior: 'smooth' });
// Flash highlight the section
el.classList.remove('section-flash-highlight');
void el.offsetWidth; // Force reflow
el.classList.add('section-flash-highlight');
setTimeout(() => el.classList.remove('section-flash-highlight'), 1500);
}
}, [data.scrollTo]);

View File

@@ -3,6 +3,7 @@ import { Accordion, Code, Stack, Text } from '@mantine/core';
import { useTranslation } from 'react-i18next';
import SectionBlock from '../shared/SectionBlock';
import SimpleArrayList from '../shared/SimpleArrayList';
import { pdfInfoAccordionStyles } from '../shared/accordionStyles';
interface OtherSectionProps {
anchorId: string;
@@ -32,7 +33,12 @@ const OtherSection: React.FC<OtherSectionProps> = ({ anchorId, other }) => {
<Text fw={600} size="sm">{t('getPdfInfo.other.layers', 'Layers')}</Text>
<SimpleArrayList arr={Array.isArray(other?.Layers) ? other?.Layers : []} />
</Stack>
<Accordion variant="separated" radius="md" defaultValue="">
<Accordion
variant="separated"
radius="md"
defaultValue=""
styles={pdfInfoAccordionStyles}
>
<Accordion.Item value="structureTree">
<Accordion.Control>
<Text fw={600} size="sm">{t('getPdfInfo.other.structureTree', 'StructureTree')}</Text>
@@ -44,7 +50,9 @@ const OtherSection: React.FC<OtherSectionProps> = ({ anchorId, other }) => {
style={{
whiteSpace: 'pre-wrap',
backgroundColor: panelBg,
color: panelText
color: panelText,
maxHeight: '20rem',
overflowY: 'auto'
}}
>
{JSON.stringify(other?.StructureTree, null, 2)}
@@ -63,7 +71,9 @@ const OtherSection: React.FC<OtherSectionProps> = ({ anchorId, other }) => {
style={{
whiteSpace: 'pre-wrap',
backgroundColor: panelBg,
color: panelText
color: panelText,
maxHeight: '400px',
overflowY: 'auto'
}}
>
{String(other?.XMPMetadata)}

View File

@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next';
import SectionBlock from '../shared/SectionBlock';
import KeyValueList from '../shared/KeyValueList';
import SimpleArrayList from '../shared/SimpleArrayList';
import { pdfInfoAccordionStyles } from '../shared/accordionStyles';
interface PerPageSectionProps {
anchorId: string;
@@ -18,7 +19,12 @@ const PerPageSection: React.FC<PerPageSectionProps> = ({ anchorId, perPage }) =>
return (
<SectionBlock title={t('getPdfInfo.sections.perPageInfo', 'Per Page Info')} anchorId={anchorId}>
{perPage && Object.keys(perPage as any).length > 0 ? (
<Accordion variant="separated" radius="md" defaultValue="">
<Accordion
variant="separated"
radius="md"
defaultValue=""
styles={pdfInfoAccordionStyles}
>
{Object.entries(perPage as any).map(([pageLabel, pageInfo]: [string, any]) => (
<Accordion.Item key={pageLabel} value={pageLabel}>
<Accordion.Control>

View File

@@ -0,0 +1,14 @@
import type { AccordionStylesNames } from '@mantine/core';
import type { CSSProperties } from 'react';
type AccordionStyles = Partial<Record<AccordionStylesNames, CSSProperties>>;
export const pdfInfoAccordionStyles: AccordionStyles = {
item: {
backgroundColor: 'var(--accordion-item-bg)',
},
control: {
backgroundColor: 'transparent',
},
};

View File

@@ -103,3 +103,28 @@
color: rgb(var(--pdf-light-text-muted));
background: linear-gradient(145deg, var(--mantine-color-gray-1) 0%, var(--mantine-color-gray-0) 100%);
}
/* Flash highlight animation for section navigation */
@keyframes section-flash {
0% {
background-color: rgba(255, 235, 59, 0);
box-shadow: none;
}
20% {
background-color: rgba(255, 235, 59, 0.35);
box-shadow: 0 0 20px rgba(255, 235, 59, 0.5);
}
50% {
background-color: rgba(255, 235, 59, 0.25);
box-shadow: 0 0 15px rgba(255, 235, 59, 0.4);
}
100% {
background-color: rgba(255, 235, 59, 0);
box-shadow: none;
}
}
.section-flash-highlight {
animation: section-flash 1.5s ease-out;
border-radius: 8px;
}

View File

@@ -256,6 +256,7 @@
--header-selected-bg: #1E88E5; /* light mode selected header matches dark */
--header-selected-fg: #FFFFFF;
--file-card-bg: #FFFFFF; /* file card background (light/dark paired) */
--accordion-item-bg: #E8EAED; /* accordion item background - more distinguishable */
/* shadows */
--drop-shadow-color: rgba(0, 0, 0, 0.08);
@@ -519,6 +520,7 @@
--header-selected-fg: #FFFFFF;
/* file card background (dark) */
--file-card-bg: #1F2329;
--accordion-item-bg: #373D45; /* accordion item background - more distinguishable */
/* shadows */
--drop-shadow-color: rgba(255, 255, 255, 0.08);