Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method to get destination from outline #1829

Open
2 tasks done
keyneston opened this issue Jun 14, 2024 · 3 comments
Open
2 tasks done

Method to get destination from outline #1829

keyneston opened this issue Jun 14, 2024 · 3 comments
Labels
enhancement New feature or request stale

Comments

@keyneston
Copy link

keyneston commented Jun 14, 2024

Before you start - checklist

  • I understand that React-PDF does not aim to be a fully-fledged PDF viewer and is only a tool to make one
  • I have checked if this feature request is not already reported

Description

I'm working on a PDF viewing tool. One of the features I want to provide is a custom outline.

From pdf.getOutline() I can successfully create a list of both top level and nested items. The thing I can't do is then link those to the specific pages.

Is there, or could there be a method on an OutlineItem that allows looking up the destination to implement custom onClick events.

Proposed solution

outline.map((item, index) => (
  item.getPageIndex()
)

Or a longer example:

  const [pageIndex, setPageIndex] = useState(0);
  useEffect(() => {
    item.getPageIndex().then((res) => setPageIndex(res))
  })
  return (
    <ListItem key={index} disablePadding>
      <ListItemButton key={index} onClick={(event) => {
        virtuosoRef.current.scrollToIndex(pageIndex);
      }}>
        <ListItemText key={index} primary={data.title} />
      </ListItemButton>
    </ListItem>
  )

Alternatives

Alternatively some way to completely customize the <Outline />. The current <Outline /> is an all or nothing affair from what I've seen.

Additional information

No response

@keyneston keyneston added the enhancement New feature or request label Jun 14, 2024
@wojtekmaj
Copy link
Owner

OutlineItem component exposes onItemClick which provides pre-looked-up properties: { dest, pageIndex, pageNumber } as args. Look at the source code of OutlineItem if you'd like to recreate the tree built by Outline component, along with getting page number/index for each item.

@keyneston
Copy link
Author

If anyone else encounters this the following code made it work. 90+% of it was copied from wojtekmaj's work.

import type { RefProxy } from 'pdfjs-dist/types/src/display/api.js';

class Ref {
  num: number;
  gen: number;

  constructor({ num, gen }: { num: number; gen: number }) {
    this.num = num;
    this.gen = gen;
  }

  toString() {
    let str = `${this.num}R`;
    if (this.gen !== 0) {
      str += this.gen;
    }
    return str;
  }
}

const getDestination = (pdf: any, item: any) => {
  if (typeof item.dest === 'string') {
    return pdf.getDestination(item.dest);
  }

  return item.dest;
};

const getPageIndex = async (pdf: any, item: any) => {
  const destination = await getDestination(pdf, item);

  if (!destination) {
    throw new Error('Destination not found.');
  }

  const [ref] = destination as [RefProxy];

  return pdf.getPageIndex(new Ref(ref));
};
 
// Callback
       <ListItemButton key={`${index}`} onClick={(_event) => {
        getPageIndex(pdf, data).then((pageIndex) => {
          virtuosoRef.current.scrollToIndex(pageIndex);

This works, but it would be nice to have these functions on the object rather than needing to copy paste them into the code.

Copy link
Contributor

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this issue will be closed in 14 days.

@github-actions github-actions bot added the stale label Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request stale
Projects
None yet
Development

No branches or pull requests

2 participants