Allow block ejection to properly apply all styles from blocks

This commit is contained in:
Andrew Kingston 2022-08-24 09:05:08 +01:00
parent ee484639b5
commit 27e44821e2
5 changed files with 263 additions and 247 deletions

View File

@ -4,6 +4,7 @@
import { blockStore } from "stores/blocks.js" import { blockStore } from "stores/blocks.js"
const component = getContext("component") const component = getContext("component")
const { styleable } = getContext("sdk")
let structureLookupMap = {} let structureLookupMap = {}
@ -18,8 +19,21 @@
} }
const eject = () => { const eject = () => {
// Start the new structure with the first top level component // Start the new structure with the root component
let definition = structureLookupMap[$component.id][0] let definition = structureLookupMap[$component.id][0]
// Copy styles from block to root component
definition._styles = {
...definition._styles,
normal: {
...definition._styles?.normal,
...$component.styles?.normal,
},
custom:
definition._styles?.custom || "" + $component.styles?.custom || "",
}
// Create component tree
attachChildren(definition, structureLookupMap) attachChildren(definition, structureLookupMap)
builderStore.actions.ejectBlock($component.id, definition) builderStore.actions.ejectBlock($component.id, definition)
} }
@ -73,4 +87,6 @@
}) })
</script> </script>
<slot /> <div use:styleable={$component.styles}>
<slot />
</div>

View File

@ -7,7 +7,6 @@
export let type export let type
export let props export let props
export let styles export let styles
export let css
export let context export let context
export let order = 0 export let order = 0
export let containsSlot = false export let containsSlot = false
@ -27,12 +26,7 @@
_component: `@budibase/standard-components/${type}`, _component: `@budibase/standard-components/${type}`,
_id: id, _id: id,
_instanceName: type[0].toUpperCase() + type.slice(1), _instanceName: type[0].toUpperCase() + type.slice(1),
_styles: { _styles: styles,
normal: {
...styles,
},
custom: css,
},
_containsSlot: containsSlot, _containsSlot: containsSlot,
...props, ...props,
} }

View File

@ -2,7 +2,6 @@
import { getContext } from "svelte" import { getContext } from "svelte"
import Block from "components/Block.svelte" import Block from "components/Block.svelte"
import BlockComponent from "components/BlockComponent.svelte" import BlockComponent from "components/BlockComponent.svelte"
import { Heading } from "@budibase/bbui"
import { makePropSafe as safe } from "@budibase/string-templates" import { makePropSafe as safe } from "@budibase/string-templates"
import { enrichSearchColumns, enrichFilter } from "utils/blocks.js" import { enrichSearchColumns, enrichFilter } from "utils/blocks.js"
@ -31,9 +30,7 @@
export let cardButtonOnClick export let cardButtonOnClick
export let linkColumn export let linkColumn
const { fetchDatasourceSchema, styleable } = getContext("sdk") const { fetchDatasourceSchema } = getContext("sdk")
const context = getContext("context")
const component = getContext("component")
let formId let formId
let dataProviderId let dataProviderId
@ -84,126 +81,132 @@
{#if schemaLoaded} {#if schemaLoaded}
<Block> <Block>
<div use:styleable={$component.styles}> <BlockComponent
<BlockComponent type="form"
type="form" bind:id={formId}
bind:id={formId} props={{ dataSource, disableValidation: true }}
props={{ dataSource, disableValidation: true }} >
> {#if title || enrichedSearchColumns?.length || showTitleButton}
{#if title || enrichedSearchColumns?.length || showTitleButton} <BlockComponent
type="container"
props={{
direction: "row",
hAlign: "stretch",
vAlign: "middle",
gap: "M",
wrap: true,
}}
styles={{
normal: {
"margin-bottom": "20px",
},
}}
order={0}
>
<BlockComponent
type="heading"
props={{
text: title,
}}
order={0}
/>
<BlockComponent <BlockComponent
type="container" type="container"
props={{ props={{
direction: "row", direction: "row",
hAlign: "stretch", hAlign: "left",
vAlign: "middle", vAlign: "middle",
gap: "M", gap: "M",
wrap: true, wrap: true,
}} }}
styles={{ order={1}
"margin-bottom": "20px",
}}
order={0}
> >
<BlockComponent {#if enrichedSearchColumns?.length}
type="heading" {#each enrichedSearchColumns as column, idx}
props={{
text: title,
}}
order={0}
/>
<BlockComponent
type="container"
props={{
direction: "row",
hAlign: "left",
vAlign: "middle",
gap: "M",
wrap: true,
}}
order={1}
>
{#if enrichedSearchColumns?.length}
{#each enrichedSearchColumns as column, idx}
<BlockComponent
type={column.componentType}
props={{
field: column.name,
placeholder: column.name,
text: column.name,
autoWidth: true,
}}
order={idx}
styles={{
width: "192px",
}}
/>
{/each}
{/if}
{#if showTitleButton}
<BlockComponent <BlockComponent
type="button" type={column.componentType}
props={{ props={{
onClick: titleButtonAction, field: column.name,
text: titleButtonText, placeholder: column.name,
type: "cta", text: column.name,
autoWidth: true,
}}
order={idx}
styles={{
normal: {
width: "192px",
},
}} }}
order={enrichedSearchColumns?.length ?? 0}
/> />
{/if} {/each}
</BlockComponent> {/if}
</BlockComponent> {#if showTitleButton}
{/if} <BlockComponent
<BlockComponent type="button"
type="dataprovider" props={{
bind:id={dataProviderId} onClick: titleButtonAction,
props={{ text: titleButtonText,
dataSource, type: "cta",
filter: enrichedFilter, }}
sortColumn, order={enrichedSearchColumns?.length ?? 0}
sortOrder, />
paginate, {/if}
limit,
}}
order={1}
>
<BlockComponent
type="repeater"
bind:id={repeaterId}
context="repeater"
props={{
dataProvider: `{{ literal ${safe(dataProviderId)} }}`,
direction: "row",
hAlign: "stretch",
vAlign: "top",
gap: "M",
noRowsMessage: "No rows found",
}}
css={`display: grid;\ngrid-template-columns: repeat(auto-fill, minmax(min(${cardWidth}px, 100%), 1fr));`}
order={0}
>
<BlockComponent
type="spectrumcard"
props={{
title: cardTitle,
subtitle: cardSubtitle,
description: cardDescription,
imageURL: cardImageURL,
horizontal: cardHorizontal,
showButton: showCardButton,
buttonText: cardButtonText,
buttonOnClick: cardButtonOnClick,
linkURL: fullCardURL,
linkPeek: cardPeek,
}}
styles={{
width: "auto",
}}
order={0}
/>
</BlockComponent> </BlockComponent>
</BlockComponent> </BlockComponent>
{/if}
<BlockComponent
type="dataprovider"
bind:id={dataProviderId}
props={{
dataSource,
filter: enrichedFilter,
sortColumn,
sortOrder,
paginate,
limit,
}}
order={1}
>
<BlockComponent
type="repeater"
bind:id={repeaterId}
context="repeater"
props={{
dataProvider: `{{ literal ${safe(dataProviderId)} }}`,
direction: "row",
hAlign: "stretch",
vAlign: "top",
gap: "M",
noRowsMessage: "No rows found",
}}
styles={{
custom: `display: grid;\ngrid-template-columns: repeat(auto-fill, minmax(min(${cardWidth}px, 100%), 1fr));`,
}}
order={0}
>
<BlockComponent
type="spectrumcard"
props={{
title: cardTitle,
subtitle: cardSubtitle,
description: cardDescription,
imageURL: cardImageURL,
horizontal: cardHorizontal,
showButton: showCardButton,
buttonText: cardButtonText,
buttonOnClick: cardButtonOnClick,
linkURL: fullCardURL,
linkPeek: cardPeek,
}}
styles={{
normal: {
width: "auto",
},
}}
order={0}
/>
</BlockComponent>
</BlockComponent> </BlockComponent>
</div> </BlockComponent>
</Block> </Block>
{/if} {/if}

View File

@ -17,46 +17,43 @@
export let vAlign export let vAlign
export let gap export let gap
let providerId
const component = getContext("component") const component = getContext("component")
const { styleable } = getContext("sdk")
let providerId
</script> </script>
<Block> <Block>
<div use:styleable={$component.styles}> <BlockComponent
<BlockComponent type="dataprovider"
type="dataprovider" context="provider"
context="provider" bind:id={providerId}
bind:id={providerId} props={{
props={{ dataSource,
dataSource, filter,
filter, sortColumn,
sortColumn, sortOrder,
sortOrder, limit,
limit, paginate,
paginate, }}
}} >
> {#if $component.empty}
{#if $component.empty} <Placeholder />
<Placeholder /> {:else}
{:else} <BlockComponent
<BlockComponent type="repeater"
type="repeater" context="repeater"
context="repeater" containsSlot
containsSlot props={{
props={{ dataProvider: `{{ literal ${safe(providerId)} }}`,
dataProvider: `{{ literal ${safe(providerId)} }}`, noRowsMessage,
noRowsMessage, direction,
direction, hAlign,
hAlign, vAlign,
vAlign, gap,
gap, }}
}} >
> <slot />
<slot /> </BlockComponent>
</BlockComponent> {/if}
{/if} </BlockComponent>
</BlockComponent>
</div>
</Block> </Block>

View File

@ -28,8 +28,7 @@
export let titleButtonURL export let titleButtonURL
export let titleButtonPeek export let titleButtonPeek
const { fetchDatasourceSchema, styleable } = getContext("sdk") const { fetchDatasourceSchema } = getContext("sdk")
const component = getContext("component")
let formId let formId
let dataProviderId let dataProviderId
@ -62,109 +61,116 @@
{#if schemaLoaded} {#if schemaLoaded}
<Block> <Block>
<div class={size} use:styleable={$component.styles}> <BlockComponent
<BlockComponent type="form"
type="form" bind:id={formId}
bind:id={formId} props={{
props={{ dataSource, disableValidation: true, editAutoColumns: true }} dataSource,
> disableValidation: true,
{#if title || enrichedSearchColumns?.length || showTitleButton} editAutoColumns: true,
size,
}}
>
{#if title || enrichedSearchColumns?.length || showTitleButton}
<BlockComponent
type="container"
props={{
direction: "row",
hAlign: "stretch",
vAlign: "middle",
gap: "M",
wrap: true,
}}
styles={{
normal: {
"margin-bottom": "20px",
},
}}
order={0}
>
<BlockComponent
type="heading"
props={{
text: title,
}}
order={0}
/>
<BlockComponent <BlockComponent
type="container" type="container"
props={{ props={{
direction: "row", direction: "row",
hAlign: "stretch", hAlign: "left",
vAlign: "middle", vAlign: "center",
gap: "M", gap: "M",
wrap: true, wrap: true,
}} }}
styles={{ order={1}
"margin-bottom": "20px",
}}
order={0}
> >
<BlockComponent {#if enrichedSearchColumns?.length}
type="heading" {#each enrichedSearchColumns as column, idx}
props={{
text: title,
}}
order={0}
/>
<BlockComponent
type="container"
props={{
direction: "row",
hAlign: "left",
vAlign: "center",
gap: "M",
wrap: true,
}}
order={1}
>
{#if enrichedSearchColumns?.length}
{#each enrichedSearchColumns as column, idx}
<BlockComponent
type={column.componentType}
props={{
field: column.name,
placeholder: column.name,
text: column.name,
autoWidth: true,
}}
styles={{
width: "192px",
}}
order={idx}
/>
{/each}
{/if}
{#if showTitleButton}
<BlockComponent <BlockComponent
type="button" type={column.componentType}
props={{ props={{
onClick: titleButtonAction, field: column.name,
text: titleButtonText, placeholder: column.name,
type: "cta", text: column.name,
autoWidth: true,
}} }}
order={enrichedSearchColumns?.length ?? 0} styles={{
normal: {
width: "192px",
},
}}
order={idx}
/> />
{/if} {/each}
</BlockComponent> {/if}
{#if showTitleButton}
<BlockComponent
type="button"
props={{
onClick: titleButtonAction,
text: titleButtonText,
type: "cta",
}}
order={enrichedSearchColumns?.length ?? 0}
/>
{/if}
</BlockComponent> </BlockComponent>
{/if}
<BlockComponent
type="dataprovider"
bind:id={dataProviderId}
props={{
dataSource,
filter: enrichedFilter,
sortColumn,
sortOrder,
paginate,
limit: rowCount,
}}
order={1}
>
<BlockComponent
type="table"
context="table"
props={{
dataProvider: `{{ literal ${safe(dataProviderId)} }}`,
columns: tableColumns,
showAutoColumns,
rowCount,
quiet,
compact,
allowSelectRows,
size,
linkRows,
linkURL,
linkColumn,
linkPeek,
}}
/>
</BlockComponent> </BlockComponent>
{/if}
<BlockComponent
type="dataprovider"
bind:id={dataProviderId}
props={{
dataSource,
filter: enrichedFilter,
sortColumn,
sortOrder,
paginate,
limit: rowCount,
}}
order={1}
>
<BlockComponent
type="table"
context="table"
props={{
dataProvider: `{{ literal ${safe(dataProviderId)} }}`,
columns: tableColumns,
showAutoColumns,
rowCount,
quiet,
compact,
allowSelectRows,
size,
linkRows,
linkURL,
linkColumn,
linkPeek,
}}
/>
</BlockComponent> </BlockComponent>
</div> </BlockComponent>
</Block> </Block>
{/if} {/if}