Inline vs Overlay vs Custom Root Container

I'm trying to put a border on specific divs around images on Amazon. They should only appear on hover (therefore I probably need to set pesuo-classes on that div). And I want to have a label ShopAdvisor with a + button next to it (therefore I think I need to add new divs regardless of if I decorate the existing HTML). The ShopAdvisor/+ div should be right-justified, which seems unimportant but it does mean the div needs context of its containing ancestor, right now it's only on the top left bc it's anchored. I know I have access to the anchor and can do all that like so
anchor.element.setAttribute(
"style",
"border: 3px solid rgb(165 180 252); box-sizing: border-box"
// Lots more CSS
)
anchor.element.setAttribute(
"style",
"border: 3px solid rgb(165 180 252); box-sizing: border-box"
// Lots more CSS
)
but it doesn't seem clean, like I'm circumventing Plasmo when I shouldn't be. I'm new to Shadow DOM but it feels like that's what I should be using lol so modifying the anchor element seems wrong. Custom Root Container does say this: "Sometimes, you'll want to completely replace Plasmo's Shadow DOM container implementation to fit your needs. For example, you might want to piggyback on an element within the web page itself instead of creating a new DOM element." And I do want to "piggyback on an element" but the name getRootContainer() and the example makes it feel like it's only suitable for one element at a time. I'm not sure what it does really. Is there an obvious way to do this that I'm missing?
No description
13 Replies
hgil
hgilOPβ€’15mo ago
@Pallas
lab
labβ€’15mo ago
but it doesn't seem clean, like I'm circumventing Plasmo when I shouldn't be. I'm new to Shadow DOM but it feels like that's what I should be using lol so modifying the anchor element seems wrong.
On the contrary - your current approach is what I'd recommend the Plasmo's abstraction of the ShadowDOM should only serves component inside itself (self-encapsulation), and it shouldn't have power over element beyond its root (i.e the anchor itself, since the ShadowDOM root are mounted under the anchor) So if you need to style the anchor or any items on the page, it's inevitable at least for content script to do it manually as you've done. The power of plasmo is that it allows you to integrate with other tools tho so instead of styling the anchor manually, you can also import a CSS/Saas/tailwind stylesheet into the target site and use classnames etc But otherwise, what you've is what I'd do. Another way of doing it is to mount a react element that take the same size as your anchor, hover absolutely, Then you can style it using other styling solution. I suspect the it doesn't seem clean part comes from the usage of manual CSS injection, which indeed feels dirty since there's no autocompletion or helper - so I'd swap that out with css import or class name, or style it via emotion and inject the element absolutely on top
lab
labβ€’15mo ago
If you just want plain CSS intelisense, use the data-text import scheme: https://docs.plasmo.com/framework/import#data-text
Plasmo Docs
Import Resolution – Plasmo
How imports work with the Plasmo Framework.
lab
labβ€’15mo ago
cc @hgil
hgil
hgilOPβ€’15mo ago
Awesome @louisgv ! Thanks that's the exact answer I wanted to hear hahah. And yep I've since ported that to Tailwind which I'm more comfortable with. You the best πŸ™
But otherwise, what you've is what I'd do. Another way of doing it is to mount a react element that take the same size as your anchor, hover absolutely, Then you can style it using other styling solution.
I did this but it caused more problems than it solved bc it then captured the pointer click events and I had to send it to the back and the position was off etc. Modifying the anchor directly is what I wanted to do since that's how I did it before porting my codebase to Plasmo
YAGPDB.xyz
YAGPDB.xyzβ€’15mo ago
Gave +1 Rep to @louisgv
hgil
hgilOPβ€’15mo ago
Hey @louisgv my bad, all I ported to Tailwind was the overlay. I was stuck on converting the anchor styling to Tailwind. You mind quickly letting me know how I should do that? The incorrect code:
import cssText from "data-text:~style.css"

export const getStyle : PlasmoGetStyle = () => {
const style = document.createElement("style")
style.textContent = cssText
return style
}

const ShopAdvisorOverlay: FC<PlasmoCSUIProps> = ({ anchor }) => {
const imageUrl = getImageUrl(anchor.element)
const productUrl = getProductUrl(anchor.element)

// Wrong
anchor.element.setAttribute(
"className",
"hover:border-2 hover:border-blue-500"
)

// Wrong
anchor.element.className = "hover:border-2 hover:border-blue-500"

// ... Functioning overlay code with Tailwind ...
import cssText from "data-text:~style.css"

export const getStyle : PlasmoGetStyle = () => {
const style = document.createElement("style")
style.textContent = cssText
return style
}

const ShopAdvisorOverlay: FC<PlasmoCSUIProps> = ({ anchor }) => {
const imageUrl = getImageUrl(anchor.element)
const productUrl = getProductUrl(anchor.element)

// Wrong
anchor.element.setAttribute(
"className",
"hover:border-2 hover:border-blue-500"
)

// Wrong
anchor.element.className = "hover:border-2 hover:border-blue-500"

// ... Functioning overlay code with Tailwind ...
I know why they're wrong - the first directly sets a className attribute in HTML which isn't a real attribute, and the second sets a class attribute with no transpilation from Tailwind to CSS. Just not sure the correct way to do it. Thanks!
YAGPDB.xyz
YAGPDB.xyzβ€’15mo ago
Gave +1 Rep to @louisgv
lab
labβ€’15mo ago
is the tailwind config pointing to that file? (it's needed to extract out the class used)
lab
labβ€’15mo ago
The 2nd one should have worked tho :-?.. The 1st one should use class instead: https://developer.mozilla.org/en-US/docs/Web/API/Element/className#notes
Element: className property - Web APIs | MDN
The className property of the Element interface gets and sets the value of the class attribute of the specified element.
lab
labβ€’15mo ago
Ooh one more thing you need to inject the style outside the bound of the shadowDOm as well so do this in the top:
import cssText from "data-text:~style.css" <- for shadowDOM injection
import "~style.css" <- for global page injection
import cssText from "data-text:~style.css" <- for shadowDOM injection
import "~style.css" <- for global page injection
Note that this import will have side effect on the overall page (tailwind can inject a lot of style reset), so I'd be careful about that
hgil
hgilOPβ€’15mo ago
Hellll yeah that worked πŸš€ thanks @louisgv I get why that was an issue now πŸ™
YAGPDB.xyz
YAGPDB.xyzβ€’15mo ago
Gave +1 Rep to @louisgv
Want results from more Discord servers?
Add your server