Question: Modifying class list of SvelteApplication
A question from @dorako:
so, my module hooks into renderApplication and modifies the html[0].classList to add a .dorako-ui class to most Applications, but this strategy does not work for Svelte Applications. I had suspected this would be the case, but I'm not sure why or how to fix it.
Would I need to submit some sort of update to the SvelteApplication to push my dorako-ui class to the options.classes?
22 Replies
My logging suggests that hook is triggering my code, but manipulating the DOM isn't working. If I manually add the .dorako-ui class to the application frame, the results are as expected (broad styling changes, replacing the background image etc.)
And you can't add the class in the
defaultOptions
classes
entry?
Also there is a onSvelteMount
callback that passes back the the element in an object.
This occurs after the render callbacks from Foundry, but not sure why you can't add a class to the ApplicationShell
component per se.
---
I suppose this brings up a possibility of making the optional classes
entry data reactive.
So you can add / remove optional classes and have the default application shells automatically update.Would this not need to be in the Svelte-based module itself? In this specific case I'm trying to affect the Item Piles module which uses TJS, but Dorako UI itself is just ol' boring JS and CSS
Gotcha, so you are trying to provide a global theming module.
One of the catches with this approach is that you have to keep in mind in general that there is an option in the core
One of the catches with this approach is that you have to keep in mind in general that there is an option in the core
Application
to limit the callbacks that are generated: baseApplication
. So renderApplication
may not always trigger for every app.
Is it perhaps CSS specificity that is causing a problem? Can you see the dorako-ui
class added when you look at the DOM in browser dev tools?Yeah, lots of the pf2e system sheets don't trigger renderApplication which is a pain, so I have a list of those specific application names.
It's not a question of CSS specificity, the class isn't in the DOM
If I add the class manually by editing the DOM in the inspector I see the expected results (my "base theme" styling applying)
I'll just take a minute to add a
renderApplication
hook in a demo and see what happens.Awesome, thanks
So what is happening in this case is that the
html
JQuery reference that is passed back in that hook is the default Foundry outer application shell that is not used when mounting a Svelte component which controls the outer application shell.
If you add the class in onSvelteMount
it works fine.
A workaround that may or may not be considered acceptable is using setTimeout in renderApplication
like this:
Actually I just verified that you don't need the timeout.
This works fine:
It also appears to work fine for normal Foundry applications.well now! Are there any potential implications of affecting the app's classlist through the element list, rather than through the jquery reference?
It should be the same element / value actually except in the SvelteApplication loading case where
html
is the unused outer application shell. By that time element
is the mounted Svelte component.
Works great and shouldn't interfere with my existing stuff
I'd say again you have to be careful in this approach as it won't universally work for any apps that define
baseApplication
. There shouldn't be any problems with the code w/ renderApplication
and using app.element[0]
. IE no need to add custom code for TRL handling.I'll probably use a strict list like I do for the system applications, so I'll only affect the stuff I know to be compatible
If this is for particular systems to like PF2E then you have a bit more freedom in specific targeting vs a broad UI overhaul module.
I primarily support PF2e, but SWADE is also supported
Yeah in that case you can check
game.system.id
I believe and generate hooks dynamically for game system specific cases where baseApplication
is defined.
unrelated question, but to what extent can I assume that the specificity-raising selectors like in .item.active.underscore.svelte-14iev2w will remain the same?
I wouldn't rely on it. The package author can modify the hash
svelte-14iev2w
, but it is also auto generated based on styles of the component, so it can change if the styles embedded in a component changes.Perfect, I can apply the styling how I want it now
You could use a regex though for styles. Quite likely the
svelte-
part won't change unless the package author completely generates a custom hash which is not as likely.
So... .item .active .underscore [class^="svelte-"]
if you had to override specific styles defined by the component.
Err.. You might have to play around with the regex. Not sure how that would work with chaining previous classes.
It looks like you got things going though! 😄Yeah I just opted for minimal touches, and I avoided the specificity class by just using other classes instead.
Thanks for the help!
If I ever do up creating a module that contains applications I'll be sure to use TJS. Just moving the window around is a world of difference as always.