I'm still pretty new to web components (see my post back in May, My First Web Component), but I've been playing with them, and other libraries that wrap them, off and on. Recently I decided to revisit something I had tried at the time I first played with the technology, a wrapper for Adobe's PDF Embed library.
At the time, I couldn't get my code working because the PDF Embed library requires the ID value of a div to use when rendering the PDF. When using a web component, you typically work with the Shadow DOM, a DOM tree "hidden" inside the web component. While it's possible to make the DOM tree accessible to outside code, the PDF Embed library still couldn't use it. It requires a string for the ID and it has to be available via 'regular' means, i.e.
document.querySelector('#TheIDValHere'). I've already filed an ER with our engineers to add support for passing in an HTML element instead, but in the meantime, I just moved on.
Until today. When randomly, this popped back into my head, and I wondered - can a web component add stuff to the wrapping DOM around it? Turns out it certainly can. It's frowned upon, and you should not do it typically, but I think this is a case where it makes sense. In my case, I decided to simply append the DIV element I need immediately after my web component.
Let me share the code, and then I'll show it in action. Here's the entire component:
I begin by importing the uuid package. This is something I've used in Node quite a bit, but it's the first time I've used it in a client-side application. I'm using this to generate a unique ID for my DIVs. This way if a person makes 2, or more, PDF Embed instances on their web page, the div will always have a unique ID. I could have made it an tag attribute, but why make the user do work they really don't need to? (Although literally as I write this, I do see why allowing the user to set it could be good - for styling purposes for example.)
Going on - my component requires the URL of the PDF and the client key (PDF Embed is free, but requires a domain-locked key). I then have optional arguments for width, height, and embed mode. (See our docs for examples of these different modes.)
Finally I have the important part - where I drop the div in the parent:
Again, this is not what you would normally do, but it worked just fine for me. Continuing on, next look at
Going back up,
loadPDF is vanilla PDF Embed code to render the document in the DIV. Oh, our library also requires a "name" value for PDFs. I think that's silly so I just create it myself based on the URL.
Once this is included in your web project, I freaking love how easy it is to use:
<pdf-embed url="https://documentcloud.adobe.com/view-sdk-demo/PDFs/Bodea Brochure.pdf" key="9861538238544ff39d37c6841344b78d" ></pdf-embed>
Or with height, width, and mode:
<pdf-embed url="./adobe-developer-terms.pdf" key="9861538238544ff39d37c6841344b78d" width="90%" height="500" embedMode="SIZED_CONTAINER" ></pdf-embed>
If you want to see the component or possibly even make some edits, you can find it here:
Edit on 10/10/2022: New location: https://github.com/cfjedimaster/webcomponents/tree/main/pdfembed
I also put it up on CodePen here:
As always, let me know what you think, and remember I'm still new at this, so be gentle. ;)