Merge pull request #7644 from Budibase/custom-css-upgrades

Custom CSS upgrades
This commit is contained in:
Martin McKeaveney 2022-09-21 15:35:42 +01:00 committed by GitHub
commit 45e9da64e2
3 changed files with 51 additions and 31 deletions

View File

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

View File

@ -1,30 +1,41 @@
<script> <script>
import { import {
TextArea,
DetailSummary, DetailSummary,
ActionButton, ActionButton,
Drawer, Drawer,
DrawerContent,
Layout,
Body,
Button, Button,
notifications, notifications,
} from "@budibase/bbui" } 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 export let componentInstance
let tempValue let tempValue
let drawer let drawer
$: bindings = getBindableProperties(
$selectedScreen,
$store.selectedComponentId
)
const openDrawer = () => { const openDrawer = () => {
tempValue = componentInstance?._styles?.custom tempValue = runtimeToReadableBinding(
bindings,
componentInstance?._styles?.custom
)
drawer.show() drawer.show()
} }
const save = async () => { const save = async () => {
try { try {
await store.actions.components.updateCustomStyle(tempValue) const value = readableToRuntimeBinding(bindings, tempValue)
await store.actions.components.updateCustomStyle(value)
} catch (error) { } catch (error) {
notifications.error("Error updating custom style") notifications.error("Error updating custom style")
} }
@ -42,26 +53,17 @@
</DetailSummary> </DetailSummary>
{#key componentInstance?._id} {#key componentInstance?._id}
<Drawer bind:this={drawer} title="Custom CSS"> <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> <Button cta slot="buttons" on:click={save}>Save</Button>
<DrawerContent slot="body"> <svelte:component
<div class="content"> this={ClientBindingPanel}
<Layout gap="S" noPadding> slot="body"
<Body size="S">Custom CSS overrides all other component styles.</Body> value={tempValue}
<TextArea bind:value={tempValue} placeholder="Enter some CSS..." /> on:change={event => (tempValue = event.detail)}
</Layout> allowJS
</div> {bindings}
</DrawerContent> />
</Drawer> </Drawer>
{/key} {/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 // Determine and apply settings to the component
$: applySettings(staticSettings, enrichedSettings, conditionalSettings) $: 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 // Scroll the selected element into view
$: selected && scrollIntoView() $: selected && scrollIntoView()
@ -151,6 +155,7 @@
children: children.length, children: children.length,
styles: { styles: {
...instance._styles, ...instance._styles,
custom: customCSS,
id, id,
empty: emptyState, empty: emptyState,
interactive, interactive,
@ -249,14 +254,18 @@
// Get raw settings // Get raw settings
let settings = {} let settings = {}
Object.entries(instance) Object.entries(instance)
.filter(([name]) => name === "_conditions" || !name.startsWith("_")) .filter(([name]) => !name.startsWith("_"))
.forEach(([key, value]) => { .forEach(([key, value]) => {
settings[key] = value settings[key] = value
}) })
// Derive static, dynamic and nested settings if the instance changed
let newStaticSettings = { ...settings } let newStaticSettings = { ...settings }
let newDynamicSettings = { ...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 => { settingsDefinition?.forEach(setting => {
if (setting.nested) { if (setting.nested) {
delete newDynamicSettings[setting.key] delete newDynamicSettings[setting.key]
@ -370,6 +379,11 @@
// setting it on initialSettings directly, we avoid a double render. // setting it on initialSettings directly, we avoid a double render.
cachedSettings[key] = allSettings[key] cachedSettings[key] = allSettings[key]
// Don't update components for internal properties
if (key.startsWith("_")) {
return
}
if (ref?.$$set) { if (ref?.$$set) {
// Programmatically set the prop to avoid svelte reactive statements // Programmatically set the prop to avoid svelte reactive statements
// firing inside components. This circumvents the problems caused by // firing inside components. This circumvents the problems caused by