Sidebar Tab Application
I have, after diving deep into the Foundry Code, figured out how to actually add new Sidebar tabs.
it's a two step process of sorts.
You need to add the actual button to reveal the Sidebar Tab, as well as actually provide the SidebarTab Application.
Only ways to add the Button is either wrap the getData() method on Sidebar, if you already use libWrapper this is the cleaner method. Alternatively you can just sort of inject the HTML for the button with jQuery.
The Tab itself is actually the easier part. Because the canonical way is already just at the end of the SidebarTab constructor.
And then the Sidebar takes care of rendering and stuff.
However, the SidebarTab has a very specific api that the Sidebar Application expects to exist. As such, the Application templates in TRL are currently insufficient to just make new SidebarTabs on their own
37 Replies
As long as you add your SidebarTab class to
CONFIG.ui
at literally any point before the setup hook is called, it will get treated like any other SidebarTab, except for the missing buttonThere isn't too much logic in
SidebarTab
, so you can implement what is necessary as a child class to SvelteApplication.
There is no ETA currently when I might provide a ready-made solution. Perhaps any effort on your side could turn into said ready-made solution. 😄
There is a mechanism to switch the element root in SvelteApplication. This would come in handy when implementing the docked vs popout modes. You can use ApplicationShell
when in popout mode and a docked component otherwise.
An example of this is in my unreleased "Better Macro Directory" demo module. It switches between ApplicationShell / TJSApplicationShell for testing this mechanism though I haven't finished the ApplicationShell / light mode styles. This is done for a dark mode / native app look and feel test.
https://github.com/typhonjs-fvtt/better-macros-directory/blob/main/src/view/BMDAppShell.svelte#L20
https://github.com/typhonjs-fvtt/better-macros-directory/blob/main/src/view/BMDAppShell.svelte#L30-L34
https://github.com/typhonjs-fvtt/better-macros-directory/blob/main/src/view/BMDAppShell.svelte#L53-L55
Quite likely though you don't need the above and just have to launch another SvelteApplication w/ ApplicationShell wrapping your sidebar content component when the sidebar tab is right clicked. Store the reference to the popped out app in the sidebar instance and if tab right clicked again call bringToTop
instead of creating a new pop out.Oh yeah, i just have to figure out which of these methods actually matter and reimplement them.
I can't just copy the foundry code because that would violate the license
Not sure if that is the case if your code is only being run on Foundry. I believe there is some leniency for small utility aspects, but a lot of it can be rewritten. You can always ask / contact them directly or in the developer channels on the mothership.
@mleahy Okay so I've finally had some time to sit down and do this. Wierdly, I can't get the application to render docked. It always appears popped out
You need to use your own component beside
ApplicationShell
for the docked sidebar. Essentially duplicating similar layout to one of the classes that extends the SidebarTab class w/ a template like (SidebarDirectory): templates/sidebar/document-directory.html
.
The JS implementation of your SidebarTab class should be able to hold an instance of the SvelteApplication that uses ApplicationShell
to wrap whatever content is in the tab.is there a way to make use of getData with SvelteApplication?
For what purpose? In the App v1 API that is used to gather data to hand to the HBS template.
I'm trying to write the base class as a SvelteApplication version of SidebarTab
As such I want to keep the variability
SidebarTab has 4 variables that are passed to the template
cssId, cssClass and tabName are the ones that immediately matter
it also passes game.user
but that matters less with svelte
Yeah... You have access to the external application that the css ID / classes assigned in
defaultOptions
with
const { application } = getContext('#external');
You could store an additional parameter for tabName in the options.
You can actually access game
directly in Svelte templates as there is a special store to do so:
import { gameState } from '@typhonjs-fvtt/runtime/store';
Then in the template use $gameState.user
.
That last bit probably wouldn't be obvious, but just a handy utility store to access game
in a template. You can always access game
in the <script>
section.
Check out how ApplicationShell
uses the options from the external app options to set CSS ID / classes:
https://github.com/typhonjs-fvtt-lib/svelte/blob/main/src/component/core/application/ApplicationShell.svelte#L374-L375I'm still having the issue of actually getting the svelte component to render at the correct position
It just renders to document root
Creating a standardized SidebarTab implementation is something useful to come up w/ an official wrapped / basic implementation that can be reused in the future. Kind of like providing a standardized TRL / Svelte ActorSheet.
Not the document-fragment created in the tab
it should show up up there, but it just kind of gets appended
If I give it the same ID as my chat tab, it just refuses to render in the first place