Merge branch 'master' of github.com:Budibase/budibase into external-tables
This commit is contained in:
commit
963d8cb679
|
@ -366,20 +366,23 @@ export const getFrontendStore = () => {
|
||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
},
|
},
|
||||||
updateStyle: async (type, name, value) => {
|
updateStyle: async (type, name, value) => {
|
||||||
let promises = []
|
|
||||||
const selected = get(selectedComponent)
|
const selected = get(selectedComponent)
|
||||||
|
if (value == null || value === "") {
|
||||||
store.update(state => {
|
delete selected._styles[type][name]
|
||||||
if (!selected._styles) {
|
} else {
|
||||||
selected._styles = {}
|
|
||||||
}
|
|
||||||
selected._styles[type][name] = value
|
selected._styles[type][name] = value
|
||||||
|
}
|
||||||
// save without messing with the store
|
await store.actions.preview.saveSelected()
|
||||||
promises.push(store.actions.preview.saveSelected())
|
},
|
||||||
return state
|
updateCustomStyle: async style => {
|
||||||
})
|
const selected = get(selectedComponent)
|
||||||
await Promise.all(promises)
|
selected._styles.custom = style
|
||||||
|
await store.actions.preview.saveSelected()
|
||||||
|
},
|
||||||
|
resetStyles: async () => {
|
||||||
|
const selected = get(selectedComponent)
|
||||||
|
selected._styles = { normal: {}, hover: {}, active: {} }
|
||||||
|
await store.actions.preview.saveSelected()
|
||||||
},
|
},
|
||||||
updateProp: (name, value) => {
|
updateProp: (name, value) => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { store, currentAsset } from "builderStore"
|
import { store, currentAsset, selectedComponent } from "builderStore"
|
||||||
import iframeTemplate from "./iframeTemplate"
|
import iframeTemplate from "./iframeTemplate"
|
||||||
import { Screen } from "builderStore/store/screenTemplates/utils/Screen"
|
import { Screen } from "builderStore/store/screenTemplates/utils/Screen"
|
||||||
import { FrontendTypes } from "../../../constants"
|
import { FrontendTypes } from "../../../constants"
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
layout,
|
layout,
|
||||||
screen,
|
screen,
|
||||||
selectedComponentId,
|
selectedComponentId,
|
||||||
|
previewType: $store.currentFrontEndType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saving pages and screens to the DB causes them to have _revs.
|
// Saving pages and screens to the DB causes them to have _revs.
|
||||||
|
@ -54,17 +55,18 @@
|
||||||
// Refresh the preview when required
|
// Refresh the preview when required
|
||||||
$: refreshContent(strippedJson)
|
$: refreshContent(strippedJson)
|
||||||
|
|
||||||
// Initialise the app when mounted
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
// Initialise the app when mounted
|
||||||
iframe.contentWindow.addEventListener(
|
iframe.contentWindow.addEventListener(
|
||||||
"bb-ready",
|
"bb-ready",
|
||||||
() => {
|
() => refreshContent(strippedJson),
|
||||||
refreshContent(strippedJson)
|
{ once: true }
|
||||||
},
|
|
||||||
{
|
|
||||||
once: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Add listener to select components
|
||||||
|
iframe.contentWindow.addEventListener("bb-select-component", data => {
|
||||||
|
store.actions.components.select({ _id: data.detail })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
*, *:before, *:after {
|
*, *:before, *:after {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
* {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src='/assets/budibase-client.js'></script>
|
<script src='/assets/budibase-client.js'></script>
|
||||||
<script>
|
<script>
|
||||||
|
@ -19,7 +22,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract data from message
|
// Extract data from message
|
||||||
const { selectedComponentId, layout, screen } = JSON.parse(event.data)
|
const { selectedComponentId, layout, screen, previewType } = JSON.parse(event.data)
|
||||||
|
|
||||||
// Set some flags so the app knows we're in the builder
|
// Set some flags so the app knows we're in the builder
|
||||||
window["##BUDIBASE_IN_BUILDER##"] = true
|
window["##BUDIBASE_IN_BUILDER##"] = true
|
||||||
|
@ -27,6 +30,7 @@
|
||||||
window["##BUDIBASE_PREVIEW_SCREEN##"] = screen
|
window["##BUDIBASE_PREVIEW_SCREEN##"] = screen
|
||||||
window["##BUDIBASE_SELECTED_COMPONENT_ID##"] = selectedComponentId
|
window["##BUDIBASE_SELECTED_COMPONENT_ID##"] = selectedComponentId
|
||||||
window["##BUDIBASE_PREVIEW_ID##"] = Math.random()
|
window["##BUDIBASE_PREVIEW_ID##"] = Math.random()
|
||||||
|
window["##BUDIBASE_PREVIEW_TYPE##"] = previewType
|
||||||
|
|
||||||
// Initialise app
|
// Initialise app
|
||||||
if (window.loadBudibase) {
|
if (window.loadBudibase) {
|
||||||
|
@ -34,15 +38,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore clicks
|
|
||||||
["click", "mousedown"].forEach(type => {
|
|
||||||
document.addEventListener(type, function(e) {
|
|
||||||
e.preventDefault()
|
|
||||||
e.stopPropagation()
|
|
||||||
return false
|
|
||||||
}, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
window.addEventListener("message", receiveMessage)
|
window.addEventListener("message", receiveMessage)
|
||||||
window.dispatchEvent(new Event("bb-ready"))
|
window.dispatchEvent(new Event("bb-ready"))
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
<TextArea
|
<TextArea
|
||||||
thin
|
thin
|
||||||
bind:value
|
bind:value
|
||||||
placeholder="Add text, or lick the objects on the left to add them to the
|
placeholder="Add text, or click the objects on the left to add them to the
|
||||||
textbox." />
|
textbox." />
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a href="https://docs.budibase.com/design/binding">
|
<a href="https://docs.budibase.com/design/binding">
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
componentPropDefinition.properties[selectedCategory.value]
|
componentPropDefinition.properties[selectedCategory.value]
|
||||||
|
|
||||||
const onStyleChanged = store.actions.components.updateStyle
|
const onStyleChanged = store.actions.components.updateStyle
|
||||||
|
const onCustomStyleChanged = store.actions.components.updateCustomStyle
|
||||||
|
const onResetStyles = store.actions.components.resetStyles
|
||||||
|
|
||||||
$: isComponentOrScreen =
|
$: isComponentOrScreen =
|
||||||
$store.currentView === "component" ||
|
$store.currentView === "component" ||
|
||||||
|
@ -93,7 +95,12 @@
|
||||||
|
|
||||||
<div class="component-props-container">
|
<div class="component-props-container">
|
||||||
{#if selectedCategory.value === 'design'}
|
{#if selectedCategory.value === 'design'}
|
||||||
<DesignView {panelDefinition} {componentInstance} {onStyleChanged} />
|
<DesignView
|
||||||
|
{panelDefinition}
|
||||||
|
{componentInstance}
|
||||||
|
{onStyleChanged}
|
||||||
|
{onCustomStyleChanged}
|
||||||
|
{onResetStyles} />
|
||||||
{:else if selectedCategory.value === 'settings'}
|
{:else if selectedCategory.value === 'settings'}
|
||||||
<SettingsView
|
<SettingsView
|
||||||
{componentInstance}
|
{componentInstance}
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
<script>
|
|
||||||
import { store, allScreens } from "builderStore"
|
|
||||||
import { FrontendTypes } from "constants"
|
|
||||||
import ComponentPropertiesPanel from "./ComponentPropertiesPanel.svelte"
|
|
||||||
import ComponentSelectionList from "./ComponentSelectionList.svelte"
|
|
||||||
|
|
||||||
const PROPERTIES_TAB = "properties"
|
|
||||||
const COMPONENT_SELECTION_TAB = "components"
|
|
||||||
|
|
||||||
let selected = PROPERTIES_TAB
|
|
||||||
|
|
||||||
const isSelected = tab => selected === tab
|
|
||||||
|
|
||||||
const selectTab = tab => (selected = tab)
|
|
||||||
|
|
||||||
const toggleTab = () =>
|
|
||||||
(selected =
|
|
||||||
selected === PROPERTIES_TAB ? COMPONENT_SELECTION_TAB : PROPERTIES_TAB)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="root">
|
|
||||||
{#if $store.currentFrontEndType === FrontendTypes.LAYOUT || $allScreens.length}
|
|
||||||
<div class="switcher">
|
|
||||||
<button
|
|
||||||
class:selected={selected === COMPONENT_SELECTION_TAB}
|
|
||||||
on:click={() => selectTab(COMPONENT_SELECTION_TAB)}>
|
|
||||||
Add
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class:selected={selected === PROPERTIES_TAB}
|
|
||||||
on:click={() => selectTab(PROPERTIES_TAB)}>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel">
|
|
||||||
{#if selected === PROPERTIES_TAB}
|
|
||||||
<ComponentPropertiesPanel {toggleTab} />
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if selected === COMPONENT_SELECTION_TAB}
|
|
||||||
<ComponentSelectionList {toggleTab} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.root {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 20px 5px 20px 10px;
|
|
||||||
border-left: solid 1px var(--grey-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switcher {
|
|
||||||
display: flex;
|
|
||||||
margin: 0px 20px 20px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switcher > button {
|
|
||||||
display: inline-block;
|
|
||||||
border: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--grey-5);
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switcher > .selected {
|
|
||||||
color: var(--ink);
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,12 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { TextArea, DetailSummary, Button } from "@budibase/bbui"
|
||||||
import PropertyGroup from "./PropertyGroup.svelte"
|
import PropertyGroup from "./PropertyGroup.svelte"
|
||||||
import FlatButtonGroup from "./FlatButtonGroup.svelte"
|
import FlatButtonGroup from "./FlatButtonGroup.svelte"
|
||||||
|
|
||||||
export let panelDefinition = {}
|
export let panelDefinition = {}
|
||||||
export let componentInstance = {}
|
export let componentInstance = {}
|
||||||
export let componentDefinition = {}
|
|
||||||
export let onStyleChanged = () => {}
|
export let onStyleChanged = () => {}
|
||||||
|
export let onCustomStyleChanged = () => {}
|
||||||
|
export let onResetStyles = () => {}
|
||||||
|
|
||||||
let selectedCategory = "normal"
|
let selectedCategory = "normal"
|
||||||
let propGroup = null
|
let propGroup = null
|
||||||
|
@ -39,11 +40,23 @@
|
||||||
properties={panelDefinition[groupName]}
|
properties={panelDefinition[groupName]}
|
||||||
styleCategory={selectedCategory}
|
styleCategory={selectedCategory}
|
||||||
{onStyleChanged}
|
{onStyleChanged}
|
||||||
{componentDefinition}
|
|
||||||
{componentInstance}
|
{componentInstance}
|
||||||
open={currentGroup === groupName}
|
open={currentGroup === groupName}
|
||||||
on:open={() => (currentGroup = groupName)} />
|
on:open={() => (currentGroup = groupName)} />
|
||||||
{/each}
|
{/each}
|
||||||
|
<DetailSummary
|
||||||
|
name={`Custom Styles${componentInstance._styles.custom ? ' *' : ''}`}
|
||||||
|
on:open={() => (currentGroup = 'custom')}
|
||||||
|
show={currentGroup === 'custom'}
|
||||||
|
thin>
|
||||||
|
<div class="custom-styles">
|
||||||
|
<TextArea
|
||||||
|
value={componentInstance._styles.custom}
|
||||||
|
on:change={event => onCustomStyleChanged(event.target.value)}
|
||||||
|
placeholder="Enter some CSS..." />
|
||||||
|
</div>
|
||||||
|
</DetailSummary>
|
||||||
|
<Button secondary wide on:click={onResetStyles}>Reset Styles</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="no-design">
|
<div class="no-design">
|
||||||
This component doesn't have any design properties.
|
This component doesn't have any design properties.
|
||||||
|
@ -85,4 +98,10 @@
|
||||||
font-size: var(--font-size-xs);
|
font-size: var(--font-size-xs);
|
||||||
color: var(--grey-5);
|
color: var(--grey-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-styles :global(textarea) {
|
||||||
|
font-family: monospace;
|
||||||
|
min-height: 120px;
|
||||||
|
font-size: var(--font-size-xs);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
$: isOptionsObject = options.every(o => typeof o === "object")
|
$: isOptionsObject = options.every(o => typeof o === "object")
|
||||||
|
|
||||||
$: selectedOption = isOptionsObject
|
$: selectedOption = isOptionsObject
|
||||||
? options.find(o => o.value === value)
|
? options.find(o => o.value === value || (o.value === "" && value == null))
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
$: if (open && selectMenu) {
|
$: if (open && selectMenu) {
|
||||||
|
|
|
@ -6,11 +6,9 @@
|
||||||
import {
|
import {
|
||||||
readableToRuntimeBinding,
|
readableToRuntimeBinding,
|
||||||
runtimeToReadableBinding,
|
runtimeToReadableBinding,
|
||||||
CAPTURE_VAR_INSIDE_MUSTACHE,
|
|
||||||
} from "builderStore/replaceBindings"
|
} from "builderStore/replaceBindings"
|
||||||
import { DropdownMenu } from "@budibase/bbui"
|
import { DropdownMenu } from "@budibase/bbui"
|
||||||
import BindingDropdown from "components/userInterface/BindingDropdown.svelte"
|
import BindingDropdown from "components/userInterface/BindingDropdown.svelte"
|
||||||
import { onMount } from "svelte"
|
|
||||||
|
|
||||||
export let label = ""
|
export let label = ""
|
||||||
export let bindable = true
|
export let bindable = true
|
||||||
|
@ -70,8 +68,8 @@
|
||||||
|
|
||||||
let temp = runtimeToReadableBinding(bindableProperties, value)
|
let temp = runtimeToReadableBinding(bindableProperties, value)
|
||||||
|
|
||||||
return value == null && props.defaultValue !== undefined
|
return value == null && props.initialValue !== undefined
|
||||||
? props.defaultValue
|
? props.initialValue
|
||||||
: temp
|
: temp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,21 +10,36 @@
|
||||||
export let onStyleChanged = () => {}
|
export let onStyleChanged = () => {}
|
||||||
export let open = false
|
export let open = false
|
||||||
|
|
||||||
|
const hasPropChanged = (style, prop) => {
|
||||||
|
// TODO: replace color picker with one that works better.
|
||||||
|
// Currently it cannot support null values, so this is a hack which
|
||||||
|
// prevents the color fields from always being marked as changed
|
||||||
|
if (!["color", "background", "border-color"].includes(prop.key)) {
|
||||||
|
if (prop.initialValue !== undefined) {
|
||||||
|
return style[prop.key] !== prop.initialValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style[prop.key] != null && style[prop.key] !== ""
|
||||||
|
}
|
||||||
|
|
||||||
$: style = componentInstance["_styles"][styleCategory] || {}
|
$: style = componentInstance["_styles"][styleCategory] || {}
|
||||||
|
$: changed = properties.some(prop => hasPropChanged(style, prop))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DetailSummary {name} on:open show={open} thin>
|
<DetailSummary name={`${name}${changed ? ' *' : ''}`} on:open show={open} thin>
|
||||||
<div>
|
{#if open}
|
||||||
{#each properties as props}
|
<div>
|
||||||
<PropertyControl
|
{#each properties as prop}
|
||||||
label={props.label}
|
<PropertyControl
|
||||||
control={props.control}
|
label={`${prop.label}${hasPropChanged(style, prop) ? ' *' : ''}`}
|
||||||
key={props.key}
|
control={prop.control}
|
||||||
value={style[props.key]}
|
key={prop.key}
|
||||||
onChange={(key, value) => onStyleChanged(styleCategory, key, value)}
|
value={style[prop.key]}
|
||||||
props={{ ...excludeProps(props, ['control', 'label']) }} />
|
onChange={(key, value) => onStyleChanged(styleCategory, key, value)}
|
||||||
{/each}
|
props={{ ...excludeProps(prop, ['control', 'label']) }} />
|
||||||
</div>
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</DetailSummary>
|
</DetailSummary>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
{ key: "layoutId", label: "Layout", control: LayoutSelect },
|
{ key: "layoutId", label: "Layout", control: LayoutSelect },
|
||||||
]
|
]
|
||||||
|
|
||||||
const layoutDefinition = [{ key: "title", label: "Title", control: Input }]
|
const layoutDefinition = []
|
||||||
|
|
||||||
const canRenderControl = (key, dependsOn) => {
|
const canRenderControl = (key, dependsOn) => {
|
||||||
let test = !isEmpty(componentInstance[dependsOn])
|
let test = !isEmpty(componentInstance[dependsOn])
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if panelDefinition && panelDefinition.length > 0}
|
{#if !isLayout && panelDefinition && panelDefinition.length > 0}
|
||||||
{#each panelDefinition as definition}
|
{#each panelDefinition as definition}
|
||||||
{#if canRenderControl(definition.key, definition.dependsOn)}
|
{#if canRenderControl(definition.key, definition.dependsOn)}
|
||||||
<PropertyControl
|
<PropertyControl
|
||||||
|
|
|
@ -24,7 +24,7 @@ export const createProps = (componentDefinition, derivedFromProps) => {
|
||||||
const props = {
|
const props = {
|
||||||
_id: uuid(),
|
_id: uuid(),
|
||||||
_component: componentDefinition._component,
|
_component: componentDefinition._component,
|
||||||
_styles: { normal: {}, hover: {}, active: {}, selected: {} },
|
_styles: { normal: {}, hover: {}, active: {} },
|
||||||
}
|
}
|
||||||
|
|
||||||
const errors = []
|
const errors = []
|
||||||
|
@ -75,7 +75,7 @@ export const makePropsSafe = (componentDefinition, props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!props._styles) {
|
if (!props._styles) {
|
||||||
props._styles = { normal: {}, hover: {}, active: {}, selected: {} }
|
props._styles = { normal: {}, hover: {}, active: {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
return props
|
return props
|
||||||
|
|
|
@ -2,18 +2,16 @@ import Input from "./PropertyPanelControls/Input.svelte"
|
||||||
import OptionSelect from "./OptionSelect.svelte"
|
import OptionSelect from "./OptionSelect.svelte"
|
||||||
import FlatButtonGroup from "./FlatButtonGroup.svelte"
|
import FlatButtonGroup from "./FlatButtonGroup.svelte"
|
||||||
import Colorpicker from "@budibase/colorpicker"
|
import Colorpicker from "@budibase/colorpicker"
|
||||||
/*
|
|
||||||
TODO: Allow for default values for all properties
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const layout = [
|
export const layout = [
|
||||||
{
|
{
|
||||||
label: "Display",
|
label: "Display",
|
||||||
key: "display",
|
key: "display",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
initialValue: "",
|
|
||||||
options: [
|
options: [
|
||||||
{ label: "N/A ", value: "N/A" },
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "Block", value: "block" },
|
||||||
|
{ label: "Inline Block", value: "inline-block" },
|
||||||
{ label: "Flex", value: "flex" },
|
{ label: "Flex", value: "flex" },
|
||||||
{ label: "Inline Flex", value: "inline-flex" },
|
{ label: "Inline Flex", value: "inline-flex" },
|
||||||
],
|
],
|
||||||
|
@ -31,15 +29,15 @@ export const layout = [
|
||||||
padding: "0px 5px",
|
padding: "0px 5px",
|
||||||
value: "columnReverse",
|
value: "columnReverse",
|
||||||
},
|
},
|
||||||
|
{ icon: "ri-close-line", value: "" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Justify",
|
label: "Justify",
|
||||||
key: "justify-content",
|
key: "justify-content",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
initialValue: "Flex Start",
|
|
||||||
options: [
|
options: [
|
||||||
{ label: "", value: "" },
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "Flex Start", value: "flex-start" },
|
{ label: "Flex Start", value: "flex-start" },
|
||||||
{ label: "Flex End", value: "flex-end" },
|
{ label: "Flex End", value: "flex-end" },
|
||||||
{ label: "Center", value: "center" },
|
{ label: "Center", value: "center" },
|
||||||
|
@ -52,8 +50,8 @@ export const layout = [
|
||||||
label: "Align",
|
label: "Align",
|
||||||
key: "align-items",
|
key: "align-items",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
initialValue: "Flex Start",
|
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "Flex Start", value: "flex-start" },
|
{ label: "Flex Start", value: "flex-start" },
|
||||||
{ label: "Flex End", value: "flex-end" },
|
{ label: "Flex End", value: "flex-end" },
|
||||||
{ label: "Center", value: "center" },
|
{ label: "Center", value: "center" },
|
||||||
|
@ -66,8 +64,9 @@ export const layout = [
|
||||||
key: "flex-wrap",
|
key: "flex-wrap",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
{ label: "wrap", value: "wrap" },
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "no wrap", value: "noWrap" },
|
{ label: "Wrap", value: "wrap" },
|
||||||
|
{ label: "No wrap", value: "nowrap" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -75,6 +74,7 @@ export const layout = [
|
||||||
key: "gap",
|
key: "gap",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -93,6 +93,7 @@ export const margin = [
|
||||||
key: "margin",
|
key: "margin",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -112,6 +113,7 @@ export const margin = [
|
||||||
key: "margin-top",
|
key: "margin-top",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -131,6 +133,7 @@ export const margin = [
|
||||||
key: "margin-right",
|
key: "margin-right",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -150,6 +153,7 @@ export const margin = [
|
||||||
key: "margin-bottom",
|
key: "margin-bottom",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -169,6 +173,7 @@ export const margin = [
|
||||||
key: "margin-left",
|
key: "margin-left",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -191,6 +196,7 @@ export const padding = [
|
||||||
key: "padding",
|
key: "padding",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -208,6 +214,7 @@ export const padding = [
|
||||||
key: "padding-top",
|
key: "padding-top",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -225,6 +232,7 @@ export const padding = [
|
||||||
key: "padding-right",
|
key: "padding-right",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -242,6 +250,7 @@ export const padding = [
|
||||||
key: "padding-bottom",
|
key: "padding-bottom",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -259,6 +268,7 @@ export const padding = [
|
||||||
key: "padding-left",
|
key: "padding-left",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0px" },
|
{ label: "None", value: "0px" },
|
||||||
{ label: "4px", value: "4px" },
|
{ label: "4px", value: "4px" },
|
||||||
{ label: "8px", value: "8px" },
|
{ label: "8px", value: "8px" },
|
||||||
|
@ -278,8 +288,8 @@ export const size = [
|
||||||
label: "Flex",
|
label: "Flex",
|
||||||
key: "flex",
|
key: "flex",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "0 1 auto",
|
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "Shrink", value: "0 1 auto" },
|
{ label: "Shrink", value: "0 1 auto" },
|
||||||
{ label: "Grow", value: "1 1 auto" },
|
{ label: "Grow", value: "1 1 auto" },
|
||||||
],
|
],
|
||||||
|
@ -333,9 +343,8 @@ export const position = [
|
||||||
label: "Position",
|
label: "Position",
|
||||||
key: "position",
|
key: "position",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
initialValue: "None",
|
|
||||||
options: [
|
options: [
|
||||||
{ label: "None", value: "none" },
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "Static", value: "static" },
|
{ label: "Static", value: "static" },
|
||||||
{ label: "Relative", value: "relative" },
|
{ label: "Relative", value: "relative" },
|
||||||
{ label: "Fixed", value: "fixed" },
|
{ label: "Fixed", value: "fixed" },
|
||||||
|
@ -375,7 +384,18 @@ export const position = [
|
||||||
label: "Z-index",
|
label: "Z-index",
|
||||||
key: "z-index",
|
key: "z-index",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: ["-9999", "-3", "-2", "-1", "0", "1", "2", "3", "9999"],
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "-9999", value: "-9999" },
|
||||||
|
{ label: "-3", value: "-3" },
|
||||||
|
{ label: "-2", value: "-2" },
|
||||||
|
{ label: "-1", value: "-1" },
|
||||||
|
{ label: "0", value: "0" },
|
||||||
|
{ label: "1", value: "1" },
|
||||||
|
{ label: "2", value: "2" },
|
||||||
|
{ label: "3", value: "3" },
|
||||||
|
{ label: "9999", value: "9999" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -384,22 +404,22 @@ export const typography = [
|
||||||
label: "Font",
|
label: "Font",
|
||||||
key: "font-family",
|
key: "font-family",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "Arial",
|
|
||||||
options: [
|
options: [
|
||||||
"Arial",
|
{ label: "Choose option", value: "" },
|
||||||
"Arial Black",
|
{ label: "Arial", value: "Arial" },
|
||||||
"Cursive",
|
{ label: "Arial Black", value: "Arial Black" },
|
||||||
"Courier",
|
{ label: "Cursive", value: "Cursive" },
|
||||||
"Comic Sans MS",
|
{ label: "Courier", value: "Courier" },
|
||||||
"Helvetica",
|
{ label: "Comic Sans MS", value: "Comic Sans MS" },
|
||||||
"Helvetica Neue",
|
{ label: "Helvetica", value: "Helvetica" },
|
||||||
"Impact",
|
{ label: "Helvetica Neue", value: "Helvetica Neue" },
|
||||||
"Inter",
|
{ label: "Impact", value: "Impact" },
|
||||||
"Lucida Sans Unicode",
|
{ label: "Inter", value: "Inter" },
|
||||||
"Roboto",
|
{ label: "Lucida Sans Unicode", value: "Lucida Sans Unicode" },
|
||||||
"Roboto Mono",
|
{ label: "Roboto", value: "Roboto" },
|
||||||
"Times New Roman",
|
{ label: "Roboto Mono", value: "Roboto Mono" },
|
||||||
"Verdana",
|
{ label: "Times New Roman", value: "Times New Roman" },
|
||||||
|
{ label: "Verdana", value: "Verdana" },
|
||||||
],
|
],
|
||||||
styleBindingProperty: "font-family",
|
styleBindingProperty: "font-family",
|
||||||
},
|
},
|
||||||
|
@ -407,25 +427,36 @@ export const typography = [
|
||||||
label: "Weight",
|
label: "Weight",
|
||||||
key: "font-weight",
|
key: "font-weight",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: ["200", "300", "400", "500", "600", "700", "800", "900"],
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "200", value: "200" },
|
||||||
|
{ label: "300", value: "300" },
|
||||||
|
{ label: "400", value: "400" },
|
||||||
|
{ label: "500", value: "500" },
|
||||||
|
{ label: "600", value: "600" },
|
||||||
|
{ label: "700", value: "700" },
|
||||||
|
{ label: "800", value: "800" },
|
||||||
|
{ label: "900", value: "900" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "size",
|
label: "size",
|
||||||
key: "font-size",
|
key: "font-size",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
"8px",
|
{ label: "Choose option", value: "" },
|
||||||
"10px",
|
{ label: "8px", value: "8px" },
|
||||||
"12px",
|
{ label: "10px", value: "10px" },
|
||||||
"14px",
|
{ label: "12px", value: "12px" },
|
||||||
"16px",
|
{ label: "14px", value: "14px" },
|
||||||
"18px",
|
{ label: "16px", value: "16px" },
|
||||||
"20px",
|
{ label: "18px", value: "18px" },
|
||||||
"24px",
|
{ label: "20px", value: "20px" },
|
||||||
"32px",
|
{ label: "24px", value: "24px" },
|
||||||
"48px",
|
{ label: "32px", value: "32px" },
|
||||||
"60px",
|
{ label: "48px", value: "48px" },
|
||||||
"72px",
|
{ label: "60px", value: "60px" },
|
||||||
|
{ label: "72px", value: "72px" },
|
||||||
],
|
],
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
|
@ -433,13 +464,21 @@ export const typography = [
|
||||||
label: "Line H",
|
label: "Line H",
|
||||||
key: "line-height",
|
key: "line-height",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: ["1", "1.25", "1.5", "1.75", "2", "4"],
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "1", value: "1" },
|
||||||
|
{ label: "1.25", value: "1.25" },
|
||||||
|
{ label: "1.5", value: "1.5" },
|
||||||
|
{ label: "1.75", value: "1.75" },
|
||||||
|
{ label: "2", value: "2" },
|
||||||
|
{ label: "4", value: "4" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Color",
|
label: "Color",
|
||||||
key: "color",
|
key: "color",
|
||||||
control: Colorpicker,
|
control: Colorpicker,
|
||||||
defaultValue: "#000",
|
initialValue: "#000",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "align",
|
label: "align",
|
||||||
|
@ -450,6 +489,7 @@ export const typography = [
|
||||||
{ icon: "ri-align-center", padding: "0px 5px", value: "center" },
|
{ icon: "ri-align-center", padding: "0px 5px", value: "center" },
|
||||||
{ icon: "ri-align-right", padding: "0px 5px", value: "right" },
|
{ icon: "ri-align-right", padding: "0px 5px", value: "right" },
|
||||||
{ icon: "ri-align-justify", padding: "0px 5px", value: "justify" },
|
{ icon: "ri-align-justify", padding: "0px 5px", value: "justify" },
|
||||||
|
{ icon: "ri-close-line", value: "" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -460,16 +500,15 @@ export const typography = [
|
||||||
{ text: "BB", value: "uppercase" },
|
{ text: "BB", value: "uppercase" },
|
||||||
{ text: "Bb", value: "capitalize" },
|
{ text: "Bb", value: "capitalize" },
|
||||||
{ text: "bb", value: "lowercase" },
|
{ text: "bb", value: "lowercase" },
|
||||||
{ text: "×", value: "none" },
|
{ icon: "ri-close-line", value: "" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Decoration",
|
label: "Decoration",
|
||||||
key: "text-decoration-line",
|
key: "text-decoration-line",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "None",
|
|
||||||
options: [
|
options: [
|
||||||
{ label: "None", value: "none" },
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "Underline", value: "underline" },
|
{ label: "Underline", value: "underline" },
|
||||||
{ label: "Overline", value: "overline" },
|
{ label: "Overline", value: "overline" },
|
||||||
{ label: "Line-through", value: "line-through" },
|
{ label: "Line-through", value: "line-through" },
|
||||||
|
@ -483,15 +522,15 @@ export const background = [
|
||||||
label: "Color",
|
label: "Color",
|
||||||
key: "background",
|
key: "background",
|
||||||
control: Colorpicker,
|
control: Colorpicker,
|
||||||
defaultValue: "#000",
|
initialValue: "#000",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Gradient",
|
label: "Gradient",
|
||||||
key: "background-image",
|
key: "background-image",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "",
|
|
||||||
options: [
|
options: [
|
||||||
{ label: "Select option", value: "" },
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "None", value: "none" },
|
||||||
{
|
{
|
||||||
label: "Warm Flame",
|
label: "Warm Flame",
|
||||||
value: "linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);",
|
value: "linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);",
|
||||||
|
@ -567,7 +606,7 @@ export const background = [
|
||||||
label: "Image",
|
label: "Image",
|
||||||
key: "background",
|
key: "background",
|
||||||
control: Input,
|
control: Input,
|
||||||
placeholder: "url",
|
placeholder: "URL",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -576,8 +615,8 @@ export const border = [
|
||||||
label: "Radius",
|
label: "Radius",
|
||||||
key: "border-radius",
|
key: "border-radius",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "None",
|
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0" },
|
{ label: "None", value: "0" },
|
||||||
{ label: "X Small", value: "0.125rem" },
|
{ label: "X Small", value: "0.125rem" },
|
||||||
{ label: "Small", value: "0.25rem" },
|
{ label: "Small", value: "0.25rem" },
|
||||||
|
@ -592,8 +631,8 @@ export const border = [
|
||||||
label: "Width",
|
label: "Width",
|
||||||
key: "border-width",
|
key: "border-width",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "None",
|
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0" },
|
{ label: "None", value: "0" },
|
||||||
{ label: "X Small", value: "0.5px" },
|
{ label: "X Small", value: "0.5px" },
|
||||||
{ label: "Small", value: "1px" },
|
{ label: "Small", value: "1px" },
|
||||||
|
@ -606,24 +645,24 @@ export const border = [
|
||||||
label: "Color",
|
label: "Color",
|
||||||
key: "border-color",
|
key: "border-color",
|
||||||
control: Colorpicker,
|
control: Colorpicker,
|
||||||
defaultValue: "#000",
|
initialValue: "#000",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Style",
|
label: "Style",
|
||||||
key: "border-style",
|
key: "border-style",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "None",
|
|
||||||
options: [
|
options: [
|
||||||
"None",
|
{ label: "Choose option", value: "" },
|
||||||
"Hidden",
|
{ label: "None", value: "none" },
|
||||||
"Dotted",
|
{ label: "Hidden", value: "hidden" },
|
||||||
"Dashed",
|
{ label: "Dotted", value: "dotted" },
|
||||||
"Solid",
|
{ label: "Dashed", value: "dashed" },
|
||||||
"Double",
|
{ label: "Solid", value: "solid" },
|
||||||
"Groove",
|
{ label: "Double", value: "double" },
|
||||||
"Ridge",
|
{ label: "Groove", value: "groove" },
|
||||||
"Inset",
|
{ label: "Ridge", value: "ridge" },
|
||||||
"Outset",
|
{ label: "Inset", value: "inset" },
|
||||||
|
{ label: "Outset", value: "outset" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -634,14 +673,22 @@ export const effects = [
|
||||||
key: "opacity",
|
key: "opacity",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
options: ["0", "0.2", "0.4", "0.6", "0.8", "1"],
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "0", value: "0" },
|
||||||
|
{ label: "0.2", value: "0.2" },
|
||||||
|
{ label: "0.4", value: "0.4" },
|
||||||
|
{ label: "0.6", value: "0.6" },
|
||||||
|
{ label: "0.8", value: "0.8" },
|
||||||
|
{ label: "1", value: "1" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Rotate",
|
label: "Rotate",
|
||||||
key: "transform",
|
key: "transform",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "0",
|
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "0" },
|
{ label: "None", value: "0" },
|
||||||
{ label: "45 deg", value: "rotate(45deg)" },
|
{ label: "45 deg", value: "rotate(45deg)" },
|
||||||
{ label: "90 deg", value: "rotate(90deg)" },
|
{ label: "90 deg", value: "rotate(90deg)" },
|
||||||
|
@ -657,8 +704,8 @@ export const effects = [
|
||||||
label: "Shadow",
|
label: "Shadow",
|
||||||
key: "box-shadow",
|
key: "box-shadow",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
defaultValue: "None",
|
|
||||||
options: [
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
{ label: "None", value: "none" },
|
{ label: "None", value: "none" },
|
||||||
{ label: "X Small", value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
|
{ label: "X Small", value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
|
||||||
{
|
{
|
||||||
|
@ -691,19 +738,20 @@ export const transitions = [
|
||||||
key: "transition-property",
|
key: "transition-property",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: [
|
options: [
|
||||||
"None",
|
{ label: "Choose option", value: "" },
|
||||||
"All",
|
{ label: "None", value: "none" },
|
||||||
"Background Color",
|
{ label: "All", value: "all" },
|
||||||
"Color",
|
{ label: "Background Color", value: "background color" },
|
||||||
"Font Size",
|
{ label: "Color", value: "color" },
|
||||||
"Font Weight",
|
{ label: "Font Size", value: "font size" },
|
||||||
"Height",
|
{ label: "Font Weight", value: "font weight" },
|
||||||
"Margin",
|
{ label: "Height", value: "height" },
|
||||||
"Opacity",
|
{ label: "Margin", value: "margin" },
|
||||||
"Padding",
|
{ label: "Opacity", value: "opacity" },
|
||||||
"Rotate",
|
{ label: "Padding", value: "padding" },
|
||||||
"Shadow",
|
{ label: "Rotate", value: "rotate" },
|
||||||
"Width",
|
{ label: "Shadow", value: "shadow" },
|
||||||
|
{ label: "Width", value: "width" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -712,13 +760,28 @@ export const transitions = [
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
placeholder: "sec",
|
placeholder: "sec",
|
||||||
options: ["0.4s", "0.6s", "0.8s", "1s", "2s", "4s"],
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "0.4s", value: "0.4s" },
|
||||||
|
{ label: "0.6s", value: "0.6s" },
|
||||||
|
{ label: "0.8s", value: "0.8s" },
|
||||||
|
{ label: "1s", value: "1s" },
|
||||||
|
{ label: "2s", value: "2s" },
|
||||||
|
{ label: "4s", value: "4s" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Ease",
|
label: "Ease",
|
||||||
key: "transition-timing-function:",
|
key: "transition-timing-function",
|
||||||
control: OptionSelect,
|
control: OptionSelect,
|
||||||
options: ["linear", "ease", "ease-in", "ease-out", "ease-in-out"],
|
options: [
|
||||||
|
{ label: "Choose option", value: "" },
|
||||||
|
{ label: "Linear", value: "linear" },
|
||||||
|
{ label: "Ease", value: "ease" },
|
||||||
|
{ label: "Ease in", value: "ease-in" },
|
||||||
|
{ label: "Ease out", value: "ease-out" },
|
||||||
|
{ label: "Ease in out", value: "ease-in-out" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { store, backendUiStore, currentAsset } from "builderStore"
|
import {
|
||||||
|
store,
|
||||||
|
backendUiStore,
|
||||||
|
currentAsset,
|
||||||
|
selectedComponent,
|
||||||
|
} from "builderStore"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { FrontendTypes } from "constants"
|
|
||||||
import CurrentItemPreview from "components/userInterface/AppPreview"
|
import CurrentItemPreview from "components/userInterface/AppPreview"
|
||||||
import ComponentPropertiesPanel from "components/userInterface/ComponentPropertiesPanel.svelte"
|
import ComponentPropertiesPanel from "components/userInterface/ComponentPropertiesPanel.svelte"
|
||||||
import ComponentSelectionList from "components/userInterface/ComponentSelectionList.svelte"
|
import ComponentSelectionList from "components/userInterface/ComponentSelectionList.svelte"
|
||||||
|
@ -43,7 +47,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if $store.currentFrontEndType === FrontendTypes.SCREEN || $store.currentFrontEndType === FrontendTypes.LAYOUT}
|
{#if $selectedComponent != null}
|
||||||
<div class="components-pane">
|
<div class="components-pane">
|
||||||
<ComponentPropertiesPanel />
|
<ComponentPropertiesPanel />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
setContext("sdk", SDK)
|
setContext("sdk", SDK)
|
||||||
setContext("component", writable({}))
|
setContext("component", writable({}))
|
||||||
setContext("data", createDataStore())
|
setContext("data", createDataStore())
|
||||||
|
setContext("screenslot", false)
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
export let definition = {}
|
export let definition = {}
|
||||||
|
|
||||||
// Get local data binding context
|
// Get contexts
|
||||||
const dataContext = getContext("data")
|
const dataContext = getContext("data")
|
||||||
|
const screenslotContext = getContext("screenslot")
|
||||||
|
|
||||||
// Create component context
|
// Create component context
|
||||||
const componentStore = writable({})
|
const componentStore = writable({})
|
||||||
|
@ -20,10 +21,15 @@
|
||||||
$: children = definition._children
|
$: children = definition._children
|
||||||
$: id = definition._id
|
$: id = definition._id
|
||||||
$: enrichedProps = enrichProps(definition, $dataContext, $bindingStore)
|
$: enrichedProps = enrichProps(definition, $dataContext, $bindingStore)
|
||||||
$: selected = id === $builderStore.selectedComponentId
|
$: styles = definition._styles
|
||||||
|
|
||||||
|
// Allow component selection in the builder preview if we're previewing a
|
||||||
|
// layout, or we're preview a screen and we're inside the screenslot
|
||||||
|
$: allowSelection =
|
||||||
|
$builderStore.previewType === "layout" || screenslotContext
|
||||||
|
|
||||||
// Update component context
|
// Update component context
|
||||||
$: componentStore.set({ id, styles: { ...definition._styles, selected } })
|
$: componentStore.set({ id, styles: { ...styles, id, allowSelection } })
|
||||||
|
|
||||||
// Gets the component constructor for the specified component
|
// Gets the component constructor for the specified component
|
||||||
const getComponentConstructor = component => {
|
const getComponentConstructor = component => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext, setContext } from "svelte"
|
||||||
import Router from "svelte-spa-router"
|
import Router from "svelte-spa-router"
|
||||||
import { routeStore } from "../store"
|
import { routeStore } from "../store"
|
||||||
import Screen from "./Screen.svelte"
|
import Screen from "./Screen.svelte"
|
||||||
|
@ -7,6 +7,9 @@
|
||||||
const { styleable } = getContext("sdk")
|
const { styleable } = getContext("sdk")
|
||||||
const component = getContext("component")
|
const component = getContext("component")
|
||||||
|
|
||||||
|
// Set context flag so components know that we're now inside the screenslot
|
||||||
|
setContext("screenslot", true)
|
||||||
|
|
||||||
// Only wrap this as an array to take advantage of svelte keying,
|
// Only wrap this as an array to take advantage of svelte keying,
|
||||||
// to ensure the svelte-spa-router is fully remounted when route config
|
// to ensure the svelte-spa-router is fully remounted when route config
|
||||||
// changes
|
// changes
|
||||||
|
|
|
@ -11,6 +11,7 @@ const loadBudibase = () => {
|
||||||
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
|
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
|
||||||
selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"],
|
selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"],
|
||||||
previewId: window["##BUDIBASE_PREVIEW_ID##"],
|
previewId: window["##BUDIBASE_PREVIEW_ID##"],
|
||||||
|
previewType: window["##BUDIBASE_PREVIEW_TYPE##"],
|
||||||
})
|
})
|
||||||
|
|
||||||
// Create app if one hasn't been created yet
|
// Create app if one hasn't been created yet
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as API from "./api"
|
import * as API from "./api"
|
||||||
import { authStore, routeStore, screenStore, bindingStore } from "./store"
|
import { authStore, routeStore, screenStore, bindingStore } from "./store"
|
||||||
import { styleable } from "./utils/styleable"
|
import { styleable } from "./utils/styleable"
|
||||||
|
import { linkable } from "./utils/linkable"
|
||||||
import { getAppId } from "./utils/getAppId"
|
import { getAppId } from "./utils/getAppId"
|
||||||
import { link as linkable } from "svelte-spa-router"
|
|
||||||
import DataProvider from "./components/DataProvider.svelte"
|
import DataProvider from "./components/DataProvider.svelte"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -7,8 +7,20 @@ const createBuilderStore = () => {
|
||||||
screen: null,
|
screen: null,
|
||||||
selectedComponentId: null,
|
selectedComponentId: null,
|
||||||
previewId: null,
|
previewId: null,
|
||||||
|
previewType: null,
|
||||||
|
}
|
||||||
|
const store = writable(initialState)
|
||||||
|
const actions = {
|
||||||
|
selectComponent: id => {
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("bb-select-component", { detail: id })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...store,
|
||||||
|
actions,
|
||||||
}
|
}
|
||||||
return writable(initialState)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const builderStore = createBuilderStore()
|
export const builderStore = createBuilderStore()
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
import { link } from "svelte-spa-router"
|
||||||
|
import { builderStore } from "../store"
|
||||||
|
|
||||||
|
export const linkable = (node, href) => {
|
||||||
|
if (get(builderStore).inBuilder) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
link(node, href)
|
||||||
|
}
|
|
@ -1,47 +1,111 @@
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
import { builderStore } from "../store"
|
||||||
|
|
||||||
|
const selectedComponentWidth = 2
|
||||||
|
const selectedComponentColor = "#4285f4"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to build a CSS string from a style object
|
* Helper to build a CSS string from a style object.
|
||||||
*/
|
*/
|
||||||
const buildStyleString = (styles, selected) => {
|
const buildStyleString = (styleObject, customStyles) => {
|
||||||
let str = ""
|
let str = ""
|
||||||
if (selected) {
|
Object.entries(styleObject).forEach(([style, value]) => {
|
||||||
styles.border = "2px solid #0055ff !important"
|
|
||||||
}
|
|
||||||
Object.entries(styles).forEach(([style, value]) => {
|
|
||||||
if (style && value != null) {
|
if (style && value != null) {
|
||||||
str += `${style}: ${value}; `
|
str += `${style}: ${value}; `
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
return str + (customStyles || "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies styles to enrich the builder preview.
|
||||||
|
* Applies styles to highlight the selected component, and allows pointer
|
||||||
|
* events for any selectable components (overriding the blanket ban on pointer
|
||||||
|
* events in the iframe HTML).
|
||||||
|
*/
|
||||||
|
const addBuilderPreviewStyles = (styleString, componentId, selectable) => {
|
||||||
|
let str = styleString
|
||||||
|
|
||||||
|
// Apply extra styles if we're in the builder preview
|
||||||
|
const state = get(builderStore)
|
||||||
|
if (state.inBuilder) {
|
||||||
|
// Allow pointer events and always enable cursor
|
||||||
|
if (selectable) {
|
||||||
|
str += ";pointer-events: all !important; cursor: pointer !important;"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Highlighted selected element
|
||||||
|
if (componentId === state.selectedComponentId) {
|
||||||
|
str += `;box-shadow: 0 0 0 ${selectedComponentWidth}px ${selectedComponentColor} inset !important;`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Svelte action to apply correct component styles.
|
* Svelte action to apply correct component styles.
|
||||||
|
* This also applies handlers for selecting components from the builder preview.
|
||||||
*/
|
*/
|
||||||
export const styleable = (node, styles = {}) => {
|
export const styleable = (node, styles = {}) => {
|
||||||
let applyNormalStyles
|
let applyNormalStyles
|
||||||
let applyHoverStyles
|
let applyHoverStyles
|
||||||
|
let selectComponent
|
||||||
|
|
||||||
|
// Kill JS even bubbling
|
||||||
|
const blockEvent = event => {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Creates event listeners and applies initial styles
|
// Creates event listeners and applies initial styles
|
||||||
const setupStyles = newStyles => {
|
const setupStyles = newStyles => {
|
||||||
const selected = newStyles.selected
|
const componentId = newStyles.id
|
||||||
const normalStyles = newStyles.normal || {}
|
const selectable = newStyles.allowSelection
|
||||||
|
const customStyles = newStyles.custom
|
||||||
|
const normalStyles = newStyles.normal
|
||||||
const hoverStyles = {
|
const hoverStyles = {
|
||||||
...normalStyles,
|
...normalStyles,
|
||||||
...newStyles.hover,
|
...newStyles.hover,
|
||||||
}
|
}
|
||||||
|
|
||||||
applyNormalStyles = () => {
|
// Applies a style string to a DOM node, enriching it for the builder
|
||||||
node.style = buildStyleString(normalStyles, selected)
|
// preview
|
||||||
|
const applyStyles = styleString => {
|
||||||
|
node.style = addBuilderPreviewStyles(styleString, componentId, selectable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Applies the "normal" style definition
|
||||||
|
applyNormalStyles = () => {
|
||||||
|
applyStyles(buildStyleString(normalStyles, customStyles))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies any "hover" styles as well as the base "normal" styles
|
||||||
applyHoverStyles = () => {
|
applyHoverStyles = () => {
|
||||||
node.style = buildStyleString(hoverStyles, selected)
|
applyStyles(buildStyleString(hoverStyles, customStyles))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler to select a component in the builder when clicking it in the
|
||||||
|
// builder preview
|
||||||
|
selectComponent = event => {
|
||||||
|
builderStore.actions.selectComponent(newStyles.id)
|
||||||
|
return blockEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add listeners to toggle hover styles
|
// Add listeners to toggle hover styles
|
||||||
node.addEventListener("mouseover", applyHoverStyles)
|
node.addEventListener("mouseover", applyHoverStyles)
|
||||||
node.addEventListener("mouseout", applyNormalStyles)
|
node.addEventListener("mouseout", applyNormalStyles)
|
||||||
|
|
||||||
|
// Add builder preview click listener
|
||||||
|
if (get(builderStore).inBuilder) {
|
||||||
|
node.addEventListener("click", selectComponent, false)
|
||||||
|
|
||||||
|
// Kill other interaction events
|
||||||
|
node.addEventListener("mousedown", blockEvent)
|
||||||
|
node.addEventListener("mouseup", blockEvent)
|
||||||
|
}
|
||||||
|
|
||||||
// Apply initial normal styles
|
// Apply initial normal styles
|
||||||
applyNormalStyles()
|
applyNormalStyles()
|
||||||
}
|
}
|
||||||
|
@ -50,6 +114,13 @@ export const styleable = (node, styles = {}) => {
|
||||||
const removeListeners = () => {
|
const removeListeners = () => {
|
||||||
node.removeEventListener("mouseover", applyHoverStyles)
|
node.removeEventListener("mouseover", applyHoverStyles)
|
||||||
node.removeEventListener("mouseout", applyNormalStyles)
|
node.removeEventListener("mouseout", applyNormalStyles)
|
||||||
|
|
||||||
|
// Remove builder preview click listener
|
||||||
|
if (get(builderStore).inBuilder) {
|
||||||
|
node.removeEventListener("click", selectComponent)
|
||||||
|
node.removeEventListener("mousedown", blockEvent)
|
||||||
|
node.removeEventListener("mouseup", blockEvent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply initial styles
|
// Apply initial styles
|
||||||
|
|
|
@ -8,8 +8,8 @@ exports.save = async function(ctx) {
|
||||||
|
|
||||||
if (!layout.props) {
|
if (!layout.props) {
|
||||||
layout = {
|
layout = {
|
||||||
...layout,
|
|
||||||
...EMPTY_LAYOUT,
|
...EMPTY_LAYOUT,
|
||||||
|
...layout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ exports.destroy = async function(ctx) {
|
||||||
)
|
)
|
||||||
).rows.map(element => element.doc.layoutId)
|
).rows.map(element => element.doc.layoutId)
|
||||||
if (layoutsUsedByScreens.includes(layoutId)) {
|
if (layoutsUsedByScreens.includes(layoutId)) {
|
||||||
ctx.throw(400, "Cannot delete a base layout")
|
ctx.throw(400, "Cannot delete a layout that's being used by a screen")
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.remove(layoutId, layoutRev)
|
await db.remove(layoutId, layoutRev)
|
||||||
|
|
|
@ -16,7 +16,17 @@ const EMPTY_LAYOUT = {
|
||||||
_id: "7fcf11e4-6f5b-4085-8e0d-9f3d44c98967",
|
_id: "7fcf11e4-6f5b-4085-8e0d-9f3d44c98967",
|
||||||
_component: "##builtin/screenslot",
|
_component: "##builtin/screenslot",
|
||||||
_styles: {
|
_styles: {
|
||||||
normal: {},
|
normal: {
|
||||||
|
flex: "1 1 auto",
|
||||||
|
display: "flex",
|
||||||
|
"flex-direction": "column",
|
||||||
|
"justify-content": "flex-start",
|
||||||
|
"align-items": "stretch",
|
||||||
|
"max-width": "100%",
|
||||||
|
"margin-left": "20px",
|
||||||
|
"margin-right": "20px",
|
||||||
|
width: "1400px",
|
||||||
|
},
|
||||||
hover: {},
|
hover: {},
|
||||||
active: {},
|
active: {},
|
||||||
selected: {},
|
selected: {},
|
||||||
|
@ -28,7 +38,16 @@ const EMPTY_LAYOUT = {
|
||||||
_styles: {
|
_styles: {
|
||||||
active: {},
|
active: {},
|
||||||
hover: {},
|
hover: {},
|
||||||
normal: {},
|
normal: {
|
||||||
|
display: "flex",
|
||||||
|
"flex-direction": "column",
|
||||||
|
"align-items": "center",
|
||||||
|
"justify-content": "flex-start",
|
||||||
|
"margin-right": "auto",
|
||||||
|
"margin-left": "auto",
|
||||||
|
"min-height": "100%",
|
||||||
|
"background-image": "#f5f5f5",
|
||||||
|
},
|
||||||
selected: {},
|
selected: {},
|
||||||
},
|
},
|
||||||
className: "",
|
className: "",
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
<script>
|
<div>
|
||||||
import { getContext } from "svelte"
|
|
||||||
|
|
||||||
const component = getContext("component")
|
|
||||||
const { styleable } = getContext("sdk")
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div use:styleable={$component.styles}>
|
|
||||||
<h1>Screen Slot</h1>
|
<h1>Screen Slot</h1>
|
||||||
<span>
|
<span>
|
||||||
The screens that you create will be displayed inside this box.
|
The screens that you create will be displayed inside this box.
|
||||||
|
|
Loading…
Reference in New Issue