Allow custom CSS to be bindable and allow overriding via conditional UI

This commit is contained in:
Andrew Kingston 2022-09-05 16:35:25 +01:00
parent eb8171dde1
commit 178dc26c16
3 changed files with 51 additions and 34 deletions

View File

@ -57,8 +57,8 @@
let dragDisabled = true
$: settings = getComponentSettings($selectedComponent?._component)?.concat({
label: "CSS",
key: "css",
label: "Custom CSS",
key: "_css",
type: "text",
})
$: settingOptions = settings.map(setting => ({

View File

@ -1,30 +1,41 @@
<script>
import {
TextArea,
DetailSummary,
ActionButton,
Drawer,
DrawerContent,
Layout,
Body,
Button,
notifications,
} from "@budibase/bbui"
import { store } from "builderStore"
import { selectedScreen, store } from "builderStore"
import ClientBindingPanel from "components/common/bindings/ClientBindingPanel.svelte"
import {
getBindableProperties,
readableToRuntimeBinding,
runtimeToReadableBinding,
} from "builderStore/dataBinding"
export let componentInstance
let tempValue
let drawer
$: bindings = getBindableProperties(
$selectedScreen,
$store.selectedComponentId
)
const openDrawer = () => {
tempValue = componentInstance?._styles?.custom
tempValue = runtimeToReadableBinding(
bindings,
componentInstance?._styles?.custom
)
drawer.show()
}
const save = async () => {
try {
await store.actions.components.updateCustomStyle(tempValue)
const value = readableToRuntimeBinding(bindings, tempValue)
await store.actions.components.updateCustomStyle(value)
} catch (error) {
notifications.error("Error updating custom style")
}
@ -42,26 +53,17 @@
</DetailSummary>
{#key componentInstance?._id}
<Drawer bind:this={drawer} title="Custom CSS">
<svelte:fragment slot="description">
Custom CSS overrides all other component styles.
</svelte:fragment>
<Button cta slot="buttons" on:click={save}>Save</Button>
<DrawerContent slot="body">
<div class="content">
<Layout gap="S" noPadding>
<Body size="S">Custom CSS overrides all other component styles.</Body>
<TextArea bind:value={tempValue} placeholder="Enter some CSS..." />
</Layout>
</div>
</DrawerContent>
<svelte:component
this={ClientBindingPanel}
slot="body"
value={tempValue}
on:change={event => (tempValue = event.detail)}
allowJS
{bindings}
/>
</Drawer>
{/key}
<style>
.content {
max-width: 800px;
margin: 0 auto;
}
.content :global(textarea) {
font-family: monospace;
min-height: 240px !important;
font-size: var(--font-size-s);
}
</style>

View File

@ -142,6 +142,10 @@
// Determine and apply settings to the component
$: applySettings(staticSettings, enrichedSettings, conditionalSettings)
// Determine custom css.
// Broken out as a separate variable to minimize reactivity updates.
$: customCSS = cachedSettings?._css
// Scroll the selected element into view
$: selected && scrollIntoView()
@ -151,6 +155,7 @@
children: children.length,
styles: {
...instance._styles,
custom: customCSS,
id,
empty: emptyState,
interactive,
@ -259,14 +264,18 @@
// Get raw settings
let settings = {}
Object.entries(instance)
.filter(([name]) => name === "_conditions" || !name.startsWith("_"))
.filter(([name]) => !name.startsWith("_"))
.forEach(([key, value]) => {
settings[key] = value
})
// Derive static, dynamic and nested settings if the instance changed
let newStaticSettings = { ...settings }
let newDynamicSettings = { ...settings }
// Attach some internal properties
newDynamicSettings["_conditions"] = instance._conditions
newDynamicSettings["_css"] = instance._styles?.custom
// Derive static, dynamic and nested settings if the instance changed
settingsDefinition?.forEach(setting => {
if (setting.nested) {
delete newDynamicSettings[setting.key]
@ -372,6 +381,10 @@
initialSettings = cachedSettings
} else {
Object.keys(allSettings).forEach(key => {
if (key === "_css") {
console.log(enrichedSettings._css)
}
const same = propsAreSame(allSettings[key], cachedSettings[key])
if (!same) {
// Updated cachedSettings (which is assigned by reference to
@ -379,8 +392,10 @@
// initial props are up to date. By setting it this way rather than
// setting it on initialSettings directly, we avoid a double render.
cachedSettings[key] = allSettings[key]
if (key === "css") {
instance._styles.custom = cachedSettings[key]
// Don't update components for internal properties
if (key.startsWith("_")) {
return
}
if (ref?.$$set) {