2020-11-13 16:42:32 +01:00
|
|
|
<script>
|
2020-11-20 10:50:10 +01:00
|
|
|
import { getContext, setContext } from "svelte"
|
2020-11-24 10:31:54 +01:00
|
|
|
import { writable } from "svelte/store"
|
2020-11-18 20:18:18 +01:00
|
|
|
import * as ComponentLibrary from "@budibase/standard-components"
|
|
|
|
import Router from "./Router.svelte"
|
2020-11-24 12:02:10 +01:00
|
|
|
import { enrichDataBinding } from "../utils"
|
|
|
|
import { bindingStore } from "../store"
|
2020-11-13 16:42:32 +01:00
|
|
|
|
2020-11-17 13:08:24 +01:00
|
|
|
export let definition = {}
|
2020-11-13 16:42:32 +01:00
|
|
|
|
2020-11-17 13:08:24 +01:00
|
|
|
// Extracts the actual component name from the library name
|
2020-11-18 20:18:18 +01:00
|
|
|
const extractComponentName = name => {
|
|
|
|
const split = name?.split("/")
|
|
|
|
return split?.[split.length - 1]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extracts valid props to pass to the real svelte component
|
2020-11-20 10:50:10 +01:00
|
|
|
const extractValidProps = component => {
|
2020-11-18 20:18:18 +01:00
|
|
|
let props = {}
|
|
|
|
Object.entries(component)
|
|
|
|
.filter(([name]) => !name.startsWith("_"))
|
|
|
|
.forEach(([key, value]) => {
|
2020-11-20 10:50:10 +01:00
|
|
|
props[key] = value
|
2020-11-18 20:18:18 +01:00
|
|
|
})
|
|
|
|
return props
|
|
|
|
}
|
|
|
|
|
2020-11-24 12:02:10 +01:00
|
|
|
// Enriches data bindings to real values based on data context
|
2020-11-24 12:28:31 +01:00
|
|
|
const enrichDataBindings = (dataContexts, dataBindings, props) => {
|
2020-11-24 12:02:10 +01:00
|
|
|
const state = {
|
2020-11-24 12:28:31 +01:00
|
|
|
...dataContexts,
|
|
|
|
...dataBindings,
|
2020-11-24 12:02:10 +01:00
|
|
|
}
|
|
|
|
let enrichedProps = {}
|
|
|
|
Object.entries(props).forEach(([key, value]) => {
|
|
|
|
enrichedProps[key] = enrichDataBinding(value, state)
|
|
|
|
})
|
|
|
|
return enrichedProps
|
|
|
|
}
|
|
|
|
|
2020-11-18 20:18:18 +01:00
|
|
|
// Gets the component constructor for the specified component
|
|
|
|
const getComponentConstructor = name => {
|
|
|
|
return name === "screenslot" ? Router : ComponentLibrary[componentName]
|
2020-11-17 13:08:24 +01:00
|
|
|
}
|
|
|
|
|
2020-11-20 10:50:10 +01:00
|
|
|
// Extract component definition info
|
2020-11-24 10:31:54 +01:00
|
|
|
$: componentName = extractComponentName(definition._component)
|
|
|
|
$: constructor = getComponentConstructor(componentName)
|
|
|
|
$: componentProps = extractValidProps(definition)
|
|
|
|
$: children = definition._children
|
2020-11-24 12:02:10 +01:00
|
|
|
$: id = definition._id
|
2020-11-24 12:28:31 +01:00
|
|
|
$: dataContext = getContext("data")
|
2020-11-24 12:02:10 +01:00
|
|
|
$: enrichedProps = enrichDataBindings(
|
2020-11-24 12:28:31 +01:00
|
|
|
$dataContext,
|
2020-11-24 12:02:10 +01:00
|
|
|
$bindingStore,
|
|
|
|
componentProps
|
|
|
|
)
|
2020-11-20 10:50:10 +01:00
|
|
|
|
2020-11-24 12:02:10 +01:00
|
|
|
// Update component context
|
|
|
|
// ID is duplicated inside style so that the "styleable" helper can set
|
|
|
|
// an ID data tag for unique reference to components
|
|
|
|
const componentStore = writable({})
|
|
|
|
setContext("component", componentStore)
|
|
|
|
$: componentStore.set({
|
|
|
|
id,
|
|
|
|
styles: { ...definition._styles, id },
|
2020-11-24 12:28:31 +01:00
|
|
|
dataContext: $dataContext.data,
|
2020-11-24 12:02:10 +01:00
|
|
|
})
|
2020-11-13 16:42:32 +01:00
|
|
|
</script>
|
|
|
|
|
2020-11-17 13:08:24 +01:00
|
|
|
{#if constructor}
|
2020-11-20 10:50:10 +01:00
|
|
|
<svelte:component this={constructor} {...enrichedProps}>
|
2020-11-17 13:08:24 +01:00
|
|
|
{#if children && children.length}
|
2020-11-24 10:31:54 +01:00
|
|
|
{#each children as child (child._id)}
|
2020-11-17 13:08:24 +01:00
|
|
|
<svelte:self definition={child} />
|
|
|
|
{/each}
|
|
|
|
{/if}
|
|
|
|
</svelte:component>
|
2020-11-13 16:42:32 +01:00
|
|
|
{/if}
|