mirror of https://github.com/Budibase/budibase.git
42 changed files with 393 additions and 341 deletions
@ -1,31 +1,35 @@ |
|||
<script> |
|||
import { componentStore } from "../store" |
|||
import { buildStyle, getValidProps } from "../utils" |
|||
import { getValidProps } from "../utils" |
|||
|
|||
export let props |
|||
export let children |
|||
export let component |
|||
export let styles |
|||
export let definition = {} |
|||
|
|||
$: componentConstructor = componentStore.actions.getComponent(component) |
|||
$: console.log("Rendering: " + component) |
|||
$: componentProps = getValidProps(definition) |
|||
$: children = definition._children |
|||
$: componentName = extractComponentName(definition._component) |
|||
$: constructor = componentStore.actions.getComponent(componentName) |
|||
$: id = `${componentName}-${definition._id}` |
|||
$: styles = { ...definition._styles, id } |
|||
|
|||
// Extracts the actual component name from the library name |
|||
function extractComponentName(name) { |
|||
console.log(name) |
|||
if (name == null) { |
|||
console.log(definition) |
|||
} |
|||
const split = name.split("/") |
|||
return split[split.length - 1] |
|||
} |
|||
|
|||
$: console.log("Rendering: " + componentName) |
|||
</script> |
|||
|
|||
{#if componentConstructor} |
|||
<div |
|||
style={buildStyle(styles)} |
|||
data-bb-component={component} |
|||
data-bb-name={component._instanceName}> |
|||
<svelte:component this={componentConstructor} {...props}> |
|||
{#if children && children.length} |
|||
{#each children as child} |
|||
<svelte:self |
|||
props={getValidProps(child)} |
|||
component={child._component} |
|||
children={child._children} |
|||
styles={child._styles.normal} /> |
|||
{/each} |
|||
{/if} |
|||
</svelte:component> |
|||
</div> |
|||
{#if constructor} |
|||
<svelte:component this={constructor} {...componentProps} {styles}> |
|||
{#if children && children.length} |
|||
{#each children as child} |
|||
<svelte:self definition={child} /> |
|||
{/each} |
|||
{/if} |
|||
</svelte:component> |
|||
{/if} |
|||
|
|||
@ -1,20 +1,24 @@ |
|||
<script> |
|||
import { screenStore } from "@budibase/component-sdk" |
|||
import { location } from "svelte-spa-router" |
|||
import { screenStore, routeStore } from "@budibase/component-sdk" |
|||
import Component from "./Component.svelte" |
|||
import { getValidProps } from "../utils" |
|||
|
|||
export let params |
|||
|
|||
// Get the screen definition for the current route |
|||
$: screenDefinition = screenStore.actions.getScreenByRoute($location) |
|||
$: screenStore.actions |
|||
$: screenDefinition = $screenStore.activeScreen |
|||
|
|||
// Update route params |
|||
$: routeStore.actions.setRouteParams(params) |
|||
|
|||
// Redirect to home page if no matching route |
|||
$: { |
|||
if (screenDefinition == null) { |
|||
routeStore.actions.navigate("/") |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
{#if screenDefinition} |
|||
<Component |
|||
component={screenDefinition.props._component} |
|||
props={getValidProps(screenDefinition.props)} |
|||
children={screenDefinition.props._children} |
|||
styles={screenDefinition.props._styles.normal} /> |
|||
<Component definition={screenDefinition.props} /> |
|||
{/if} |
|||
|
|||
@ -1,3 +1 @@ |
|||
import { createComponentStore } from "./components" |
|||
|
|||
export const componentStore = createComponentStore() |
|||
export { componentStore } from "./components" |
|||
|
|||
@ -0,0 +1 @@ |
|||
export const DataProvider = "bb-data-provider" |
|||
@ -0,0 +1,24 @@ |
|||
import { writable } from "svelte/store" |
|||
|
|||
export const createDataProviderContext = () => { |
|||
const store = writable({ |
|||
rows: [], |
|||
table: null, |
|||
}) |
|||
const setRows = rows => { |
|||
store.update(state => { |
|||
state.rows = rows |
|||
return state |
|||
}) |
|||
} |
|||
const setTable = table => { |
|||
store.update(state => { |
|||
state.table = table |
|||
return state |
|||
}) |
|||
} |
|||
return { |
|||
subscribe: store.subscribe, |
|||
actions: { setRows, setTable }, |
|||
} |
|||
} |
|||
@ -1 +1,2 @@ |
|||
export const RouterContext = "bb-router" |
|||
export * from "./dataProvider" |
|||
export * as ContextTypes from "./contextTypes" |
|||
|
|||
@ -1,5 +1,5 @@ |
|||
export * from "./api" |
|||
export * from "./store" |
|||
export * as ContextTypes from "./context" |
|||
export { getAppId } from "./utils" |
|||
export { link } from "svelte-spa-router" |
|||
export * from "./context" |
|||
export * from "./utils" |
|||
export { link as linkable } from "svelte-spa-router" |
|||
|
|||
@ -1,9 +1,4 @@ |
|||
import { createConfigStore } from "./config" |
|||
import { createAuthStore } from "./auth" |
|||
import { createRouteStore } from "./routes" |
|||
import { createScreenStore } from "./screens" |
|||
|
|||
export const configStore = createConfigStore() |
|||
export const authStore = createAuthStore() |
|||
export const routeStore = createRouteStore() |
|||
export const screenStore = createScreenStore() |
|||
export { configStore } from "./config" |
|||
export { authStore } from "./auth" |
|||
export { routeStore } from "./routes" |
|||
export { screenStore } from "./screens" |
|||
|
|||
@ -1,25 +1,33 @@ |
|||
import { writable, derived, get } from "svelte/store" |
|||
|
|||
const initialState = [] |
|||
import { writable, derived } from "svelte/store" |
|||
import { routeStore } from "./routes" |
|||
|
|||
export const createScreenStore = () => { |
|||
const store = writable(initialState) |
|||
const routeLookupMap = derived(store, $screens => { |
|||
let map = {} |
|||
$screens.forEach(screen => { |
|||
map[screen.route] = screen |
|||
}) |
|||
return map |
|||
console.log("CREATE SCREEN STORE") |
|||
|
|||
const screens = writable([]) |
|||
const store = derived([screens, routeStore], ([$screens, $routeStore]) => { |
|||
const activeScreen = $screens.find( |
|||
screen => screen.route === $routeStore.activeRoute |
|||
) |
|||
return { |
|||
screens: $screens, |
|||
activeScreen, |
|||
} |
|||
}) |
|||
|
|||
const fetchScreens = () => { |
|||
const frontendDefinition = window["##BUDIBASE_FRONTEND_DEFINITION##"] |
|||
store.set(frontendDefinition.screens) |
|||
screens.set(frontendDefinition.screens) |
|||
} |
|||
const getScreenByRoute = path => { |
|||
return get(routeLookupMap)[path] |
|||
|
|||
return { |
|||
subscribe: store.subscribe, |
|||
actions: { fetchScreens }, |
|||
} |
|||
store.actions = { fetchScreens, getScreenByRoute } |
|||
} |
|||
|
|||
return store |
|||
if (!window.bbSDKScreenStore) { |
|||
window.bbSDKScreenStore = createScreenStore() |
|||
} |
|||
|
|||
export const screenStore = window.bbSDKScreenStore |
|||
|
|||
@ -1 +1,2 @@ |
|||
export { getAppId } from "./getAppId" |
|||
export { styleable } from "./styleable" |
|||
|
|||
@ -0,0 +1,46 @@ |
|||
const buildStyleString = styles => { |
|||
let str = "" |
|||
Object.entries(styles).forEach(([style, value]) => { |
|||
if (style && value) { |
|||
str += `${style}: ${value}; ` |
|||
} |
|||
}) |
|||
return str |
|||
} |
|||
|
|||
/** |
|||
* Svelte action to apply correct component styles. |
|||
*/ |
|||
export const styleable = (node, styles = {}) => { |
|||
const normalStyles = styles.normal || {} |
|||
const hoverStyles = { |
|||
...normalStyles, |
|||
...styles.hover, |
|||
} |
|||
|
|||
function applyNormalStyles() { |
|||
node.style = buildStyleString(normalStyles) |
|||
} |
|||
|
|||
function applyHoverStyles() { |
|||
node.style = buildStyleString(hoverStyles) |
|||
} |
|||
|
|||
// Add listeners to toggle hover styles
|
|||
node.addEventListener("mouseover", applyHoverStyles) |
|||
node.addEventListener("mouseout", applyNormalStyles) |
|||
|
|||
// Apply normal styles initially
|
|||
applyNormalStyles() |
|||
|
|||
// Also apply data tags so we know how to reference each component
|
|||
node.setAttribute("data-bb-id", styles.id) |
|||
|
|||
return { |
|||
// Clean up event listeners when component is destroyed
|
|||
destroy: () => { |
|||
node.removeEventListener("mouseover", applyHoverStyles) |
|||
node.removeEventListener("mouseout", applyNormalStyles) |
|||
}, |
|||
} |
|||
} |
|||
@ -1,58 +1,61 @@ |
|||
<script> |
|||
import { styleable } from "@budibase/component-sdk" |
|||
|
|||
export let className = "" |
|||
export let type = "div" |
|||
|
|||
$: console.log(type) |
|||
export let styles |
|||
</script> |
|||
|
|||
{#if type === 'div'} |
|||
<div> |
|||
<div use:styleable={styles}> |
|||
<slot /> |
|||
</div> |
|||
{:else if type === 'header'} |
|||
<header> |
|||
<header use:styleable={styles}> |
|||
<slot /> |
|||
</header> |
|||
{:else if type === 'main'} |
|||
<main> |
|||
<main use:styleable={styles}> |
|||
<slot /> |
|||
</main> |
|||
{:else if type === 'footer'} |
|||
<footer> |
|||
<footer use:styleable={styles}> |
|||
<slot /> |
|||
</footer> |
|||
{:else if type === 'aside'} |
|||
<aside> |
|||
<aside use:styleable={styles}> |
|||
<slot /> |
|||
</aside> |
|||
{:else if type === 'summary'} |
|||
<summary> |
|||
<summary use:styleable={styles}> |
|||
<slot /> |
|||
</summary> |
|||
{:else if type === 'details'} |
|||
<details> |
|||
<details use:styleable={styles}> |
|||
<slot /> |
|||
</details> |
|||
{:else if type === 'article'} |
|||
<article> |
|||
<article use:styleable={styles}> |
|||
<slot /> |
|||
</article> |
|||
{:else if type === 'nav'} |
|||
<nav> |
|||
<nav use:styleable={styles}> |
|||
<slot /> |
|||
</nav> |
|||
{:else if type === 'mark'} |
|||
<mark><slot /></mark> |
|||
<mark use:styleable={styles}> |
|||
<slot /> |
|||
</mark> |
|||
{:else if type === 'figure'} |
|||
<figure> |
|||
<figure use:styleable={styles}> |
|||
<slot /> |
|||
</figure> |
|||
{:else if type === 'figcaption'} |
|||
<figcaption> |
|||
<figcaption use:styleable={styles}> |
|||
<slot /> |
|||
</figcaption> |
|||
{:else if type === 'paragraph'} |
|||
<p> |
|||
<p use:styleable={styles}> |
|||
<slot /> |
|||
</p> |
|||
{/if} |
|||
|
|||
@ -1,10 +1,10 @@ |
|||
<script> |
|||
import Form from "./Form.svelte" |
|||
|
|||
export let _bb |
|||
export let table |
|||
export let title |
|||
export let buttonText |
|||
export let styles |
|||
</script> |
|||
|
|||
<Form {_bb} {table} {title} {buttonText} wide={true} /> |
|||
<Form {styles} {table} {title} {buttonText} wide /> |
|||
|
|||
@ -1,5 +1,23 @@ |
|||
<script> |
|||
import { styleable } from "@budibase/component-sdk" |
|||
|
|||
export let embed |
|||
export let styles |
|||
</script> |
|||
|
|||
{@html embed} |
|||
<div use:styleable={styles}> |
|||
{@html embed} |
|||
</div> |
|||
|
|||
<style> |
|||
div { |
|||
position: relative; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: stretch; |
|||
} |
|||
div :global(> *) { |
|||
flex: 1 1 auto; |
|||
} |
|||
</style> |
|||
|
|||
@ -1,29 +1,22 @@ |
|||
<script> |
|||
import { styleable } from "@budibase/component-sdk" |
|||
|
|||
export let className = "" |
|||
export let type |
|||
export let text = "" |
|||
|
|||
export let _bb |
|||
|
|||
let containerElement |
|||
|
|||
$: containerElement && |
|||
!text && |
|||
_bb.props.children && |
|||
_bb.props.children.length && |
|||
_bb.attachChildren(containerElement) |
|||
export let styles |
|||
</script> |
|||
|
|||
{#if type === 'h1'} |
|||
<h1 class={className} bind:this={containerElement}>{text}</h1> |
|||
<h1 class={className} use:styleable={styles}>{text}</h1> |
|||
{:else if type === 'h2'} |
|||
<h2 class={className} bind:this={containerElement}>{text}</h2> |
|||
<h2 class={className} use:styleable={styles}>{text}</h2> |
|||
{:else if type === 'h3'} |
|||
<h3 class={className} bind:this={containerElement}>{text}</h3> |
|||
<h3 class={className} use:styleable={styles}>{text}</h3> |
|||
{:else if type === 'h4'} |
|||
<h4 class={className} bind:this={containerElement}>{text}</h4> |
|||
<h4 class={className} use:styleable={styles}>{text}</h4> |
|||
{:else if type === 'h5'} |
|||
<h5 class={className} bind:this={containerElement}>{text}</h5> |
|||
<h5 class={className} use:styleable={styles}>{text}</h5> |
|||
{:else if type === 'h6'} |
|||
<h6 class={className} bind:this={containerElement}>{text}</h6> |
|||
<h6 class={className} use:styleable={styles}>{text}</h6> |
|||
{/if} |
|||
|
|||
Loading…
Reference in new issue