feat(components): Initialize component state and enable property mapping

- Ensure every component has an initialized state, defaulting to empty.
- Implement property mapping to synchronize states between parent and child components.
This commit is contained in:
Samuel Andert
2023-07-24 15:00:05 +02:00
parent 5b7c49fd58
commit e12f6bcf05
6 changed files with 106 additions and 19 deletions

View File

@ -1,17 +1,67 @@
<script lang="ts">
import Composite from './Composite.svelte'; // Recursive import
import Composite from './Composite.svelte';
import components from '$lib/componentLoader';
import { getContextStore } from '$lib/stores/contextStore.ts';
import { createComponentStore, getComponentStore } from '$lib/stores/componentStores.ts';
export let componentsData = {
layout: '',
children: []
};
function initializeComponentState(child) {
// This will either retrieve the existing store or create a default one
child.store = createComponentStore(child.id, child.state || {});
if (child.children) {
child.children.forEach(initializeComponentState);
}
}
$: if (componentsData && componentsData.children) {
componentsData.children.forEach((child) => {
child.store = getContextStore(child.componentName);
});
componentsData.children.forEach(initializeComponentState);
}
function mapAndSubscribe(component) {
console.log('Mapping and subscribing for:', component.id); // Debug line
if (component.map) {
const localStore = getComponentStore(component.id);
// Use the subscribe method to log and work with the store's value
localStore.subscribe((localStoreValue) => {
console.log('Local store before mapping:', localStoreValue);
});
for (const [localKey, external] of Object.entries(component.map)) {
const [externalID, externalKey] = external.split('.').map((item) => item.trim());
const externalStore = getComponentStore(externalID);
if (externalStore) {
externalStore.subscribe((externalState) => {
console.log('External state:', externalState); // Debug line
if (externalState && externalKey in externalState) {
localStore.update((storeValue) => {
storeValue = storeValue || {};
storeValue[localKey] = externalState[externalKey];
return storeValue;
});
}
});
}
}
// Use the subscribe method again if you want to log after mapping
localStore.subscribe((localStoreValue) => {
console.log('Local store after mapping:', localStoreValue);
});
}
if (component.children) {
component.children.forEach(mapAndSubscribe);
}
}
$: if (componentsData && componentsData.children) {
componentsData.children.forEach(mapAndSubscribe);
}
async function getComponent(componentName) {
@ -23,12 +73,14 @@
}
</script>
<!-- Rest of the component markup remains unchanged -->
<div class="grid w-full h-full" style="display: grid; {componentsData.layout || ''}">
{#each componentsData.children as component (component.id)}
{#await getComponent(component.componentName) then Component}
{#if Component}
<div class="w-full h-full overflow-hidden {component.slot}">
<svelte:component this={Component} {...component.props} />
<svelte:component this={Component} id={component.id} {...component.props} />
{#if component.actions}
<div class="flex justify-end p-4">