Allow custom CSS to be bindable and allow overriding via conditional UI
This commit is contained in:
parent
eb8171dde1
commit
178dc26c16
|
@ -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 => ({
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue