Why is this element not reactive?

I'm using this element in two partials within the same component:
<TJSSelect options="{manaTypes}" bind:value='{$doc.system.manaType}' />
<TJSSelect options="{manaTypes}" bind:value='{$doc.system.manaType}' />
In both partials, $doc comes from context:
<script>
import { getContext } from "svelte";
const doc = getContext("#doc");
</script>
<script>
import { getContext } from "svelte";
const doc = getContext("#doc");
</script>
When I change the value of one select, the other only updates if I close and re-open the item sheet. The parent component of the two partials is ItemSheetShell.svelte:
<svelte:options accessors={true} />

<script>
import { ApplicationShell } from "@typhonjs-fvtt/runtime/svelte/component/core";
import { setContext, getContext } from "svelte";
import SpellHeader from "~/components/item/type/spell/SpellHeader.svelte";
import SpellTabs from "~/components/item/type/spell/SpellTabs.svelte";

export let elementRoot; //- passed in by SvelteApplication
export let documentStore; //- passed in by DocumentSheet.js where it attaches DocumentShell to the DOM body
export let document; //- passed in by DocumentSheet.js where it attaches DocumentShell to the DOM body
const tabMap = {
spell: SpellTabs,
};
const application = getContext("external").application;
let activeTab = "description";

setContext("#doc", documentStore);

$: item = $documentStore;

</script>

<template lang="pug">
svelte:component(this="{headerMap[item.type]}")
svelte:component(this="{tabMap[item.type]}")
</template>
<svelte:options accessors={true} />

<script>
import { ApplicationShell } from "@typhonjs-fvtt/runtime/svelte/component/core";
import { setContext, getContext } from "svelte";
import SpellHeader from "~/components/item/type/spell/SpellHeader.svelte";
import SpellTabs from "~/components/item/type/spell/SpellTabs.svelte";

export let elementRoot; //- passed in by SvelteApplication
export let documentStore; //- passed in by DocumentSheet.js where it attaches DocumentShell to the DOM body
export let document; //- passed in by DocumentSheet.js where it attaches DocumentShell to the DOM body
const tabMap = {
spell: SpellTabs,
};
const application = getContext("external").application;
let activeTab = "description";

setContext("#doc", documentStore);

$: item = $documentStore;

</script>

<template lang="pug">
svelte:component(this="{headerMap[item.type]}")
svelte:component(this="{tabMap[item.type]}")
</template>
Which sets the context.
2 Replies
geoidesic
geoidesic16mo ago
I guess I'm misunderstanding how to use TJSSelect. There aren't any examples of how to use it that I can see in essentials-esm-svelte. I can see it wants a store prop but I'm not sure how to pass my #doc store so that it will update the correct k/v pair in there? It feels like it wants a separate store for the k/v pair but that seems redundant as the k/v pair is already part of the Item document store. Anyhow I created my own Select element to get around the issue.
TyphonJS (Michael)
Yeah, I'll be getting more demos up ~soon that show how to use the svelte-standard components. The big difference w/ most of the svelte-standard components is that they can be configured in a data oriented way, so you normally pass a single configuration object w/ a store property for the externally connected store. This won't work for Foundry documents until I get to the second phase of TJSDocument worked out where you can create automatic stores for document properties. ---- You'll want to be careful with binding document properties directly as this won't update the document itself. You need to call update on the document. It will read the current value, but not do a DB update on any changes. bind:value='{$doc.system.manaType}'