Release: `svelte-standard` 0.0.20 - More Svelte sidebar apps

Greets @FVTT ▹ Developer. Following on the heels of svelte-standard 0.0.19 the latest release further extends FVTTSidebarControl allowing you to replace an existing Foundry sidebar app w/ a Svelte powered sidebar and also the ability to remove a stock Foundry sidebar app from the core Sidebar app. The replacement aspect was requested and I had a good idea that it would be useful. Please do report any problems using this new API. Replacing existing sidebars will require you to augment required methods in the given core sidebar app being replaced. Use FVTTSidebarControl.wait().then() to augment as necessary. A very basic and incomplete example of augmenting combat tracker replacement is in the sample code below. There is no new developer overview video as the essentials are more or less the same except there are new FVTTSidebarControl.remove and FVTTSidebarControl.replace methods. Do feel free to checkout the last update video though: https://www.youtube.com/watch?v=otmXoOtp7NQ Basic usage:
import { FVTTSidebarControl } from '@typhonjs-fvtt/svelte-standard/application';

Hooks.once('setup', () =>
{
// Replaces the core combat sidebar w/ new Svelte implementation.
FVTTSidebarControl.replace({
replaceId: 'combat', // Replaces core combat sidebar app.
icon: 'fas fa-dice-d10', // FontAwesome icon.
title: 'COMBAT', // Title of popout sidebar app; can be language string.
tooltip: 'COMBAT', // Tooltip for sidebar tab.
svelte: { // Svelte configuration object...
class: CombatTab // A Svelte component.
context: {
combatControl
}
}
});

// Removes the core cards sidebar.
FVTTSidebarControl.remove({
removeId: 'cards' // Removes core cards sidebar app.
});

// For replaced sidebars like `combat` you will need to augment the API that Foundry
// expects the `globalThis.ui.combat` app to have like `initialize`. You should // provide a prop / context for the Svelte component defining the new combat sidebar. // Add a method initialize that invokes `initialize` on your control / model code.
FVTTSidebarControl.wait().then(() =>
{
globalThis.ui.combat = Object.assign(globalThis.ui.combat, {
initialize: (data) => combatControl.initialize(data)
// Other method stubs as necessary
});
});
});
import { FVTTSidebarControl } from '@typhonjs-fvtt/svelte-standard/application';

Hooks.once('setup', () =>
{
// Replaces the core combat sidebar w/ new Svelte implementation.
FVTTSidebarControl.replace({
replaceId: 'combat', // Replaces core combat sidebar app.
icon: 'fas fa-dice-d10', // FontAwesome icon.
title: 'COMBAT', // Title of popout sidebar app; can be language string.
tooltip: 'COMBAT', // Tooltip for sidebar tab.
svelte: { // Svelte configuration object...
class: CombatTab // A Svelte component.
context: {
combatControl
}
}
});

// Removes the core cards sidebar.
FVTTSidebarControl.remove({
removeId: 'cards' // Removes core cards sidebar app.
});

// For replaced sidebars like `combat` you will need to augment the API that Foundry
// expects the `globalThis.ui.combat` app to have like `initialize`. You should // provide a prop / context for the Svelte component defining the new combat sidebar. // Add a method initialize that invokes `initialize` on your control / model code.
FVTTSidebarControl.wait().then(() =>
{
globalThis.ui.combat = Object.assign(globalThis.ui.combat, {
initialize: (data) => combatControl.initialize(data)
// Other method stubs as necessary
});
});
});
2 Replies
Solidor
Solidor2y ago
Temptation to completely rewrite and customize combat building I like how that's actually the example you are using...
TyphonJS (Michael)
No doubt! Technically it is possible to completely replace all sidebar tabs w/ a slick Svelte implementation. I'll leave this "up to the reader" / others for implementation details. Folks will have to investigate the core sidebar apps being replaced to mimic the API provided. For instance the combat sidebar is CombatTracker and does have several additional methods to implement. You could though quite likely create your own class to make that easier for code separation and documentation. Something like this:
FVTTSidebarControl.wait().then(() =>
{
globalThis.ui.combat = Object.assign(combatControl, globalThis.ui.combat);
});

// Where `combatControl` is your control / model code for the Svelte side and also implements the API from `CombatTracker`.
class CombatControl
{
constructor() { ... }

/**
* Return an array of Combat encounters which occur within the current Scene.
* @type {Combat[]}
*/
get combats() {
return game.combats.combats;
}

initialize({combat=null, render=true}={}) { ... }

// All other relevant methods in `CombatTracker` core app, etc.
}
FVTTSidebarControl.wait().then(() =>
{
globalThis.ui.combat = Object.assign(combatControl, globalThis.ui.combat);
});

// Where `combatControl` is your control / model code for the Svelte side and also implements the API from `CombatTracker`.
class CombatControl
{
constructor() { ... }

/**
* Return an array of Combat encounters which occur within the current Scene.
* @type {Combat[]}
*/
get combats() {
return game.combats.combats;
}

initialize({combat=null, render=true}={}) { ... }

// All other relevant methods in `CombatTracker` core app, etc.
}
I think I'll add one more data field in the add / replace methods defining an object to merge into the default "app" shim that is placed in globalThis.ui for the given sidebars. This will make it a bit simpler without having to do the merging manually through the wait mechanism described in this post. I should just say again. svelte-standard is a bit more free-form, so anything that is "extra" to the core app dev experience can be iterated on much quicker in svelte-standard. So hearing any feedback from devs trying to create custom Svelte sidebars can inform on making things better.
Want results from more Discord servers?
Add your server