forked from tsai/budibase
20 changed files with 963 additions and 262 deletions
@ -0,0 +1,43 @@ |
|||||
|
<script> |
||||
|
export let categories = [] |
||||
|
export let selectedCategory = {} |
||||
|
export let onClick = category => {} |
||||
|
</script> |
||||
|
|
||||
|
<ul class="tabs"> |
||||
|
{#each categories as category} |
||||
|
<li |
||||
|
on:click={() => onClick(category)} |
||||
|
class:active={selectedCategory === category}> |
||||
|
{category.name} |
||||
|
</li> |
||||
|
{/each} |
||||
|
|
||||
|
</ul> |
||||
|
|
||||
|
<style> |
||||
|
.tabs { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
list-style: none; |
||||
|
margin: 0 auto; |
||||
|
padding: 0 30px; |
||||
|
border-bottom: 1px solid #d8d8d8; |
||||
|
|
||||
|
font-size: 14px; |
||||
|
font-weight: 500; |
||||
|
letter-spacing: 0.14px; |
||||
|
} |
||||
|
|
||||
|
li { |
||||
|
color: #808192; |
||||
|
margin: 0 5px; |
||||
|
padding: 0 8px; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
.active { |
||||
|
border-bottom: solid 3px #0055ff; |
||||
|
color: #393c44; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,62 @@ |
|||||
|
<script> |
||||
|
import PropertyGroup from "./PropertyGroup.svelte" |
||||
|
import FlatButtonGroup from "./FlatButtonGroup.svelte" |
||||
|
|
||||
|
export let panelDefinition = {} |
||||
|
export let componentInstance = {} |
||||
|
export let componentDefinition = {} |
||||
|
export let onPropChanged = () => {} |
||||
|
|
||||
|
let selectedCategory = "desktop" |
||||
|
|
||||
|
const getProperties = name => panelDefinition.properties[name] |
||||
|
|
||||
|
function onChange(category) { |
||||
|
selectedCategory = category |
||||
|
} |
||||
|
|
||||
|
const buttonProps = [ |
||||
|
{ value: "desktop", text: "Desktop" }, |
||||
|
{ value: "mobile", text: "Mobile" }, |
||||
|
{ value: "hover", text: "Hover" }, |
||||
|
{ value: "active", text: "Active" }, |
||||
|
{ value: "selected", text: "Selected" }, |
||||
|
] |
||||
|
|
||||
|
$: propertyGroupNames = |
||||
|
!!panelDefinition.properties && Object.keys(panelDefinition.properties) |
||||
|
</script> |
||||
|
|
||||
|
<div class="design-view-container"> |
||||
|
|
||||
|
<div class="design-view-state-categories"> |
||||
|
<FlatButtonGroup value={selectedCategory} {buttonProps} {onChange} /> |
||||
|
</div> |
||||
|
|
||||
|
<div class="design-view-property-groups"> |
||||
|
{#each propertyGroupNames as groupName} |
||||
|
<PropertyGroup |
||||
|
name={groupName} |
||||
|
properties={getProperties(groupName)} |
||||
|
{onPropChanged} |
||||
|
{componentDefinition} |
||||
|
{componentInstance} /> |
||||
|
{/each} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.design-view-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.design-view-state-categories { |
||||
|
flex: 0 0 50px; |
||||
|
} |
||||
|
|
||||
|
.design-view-property-groups { |
||||
|
flex: 1; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,38 @@ |
|||||
|
<script> |
||||
|
export let value = "" |
||||
|
export let text = "" |
||||
|
export let icon = "" |
||||
|
export let onClick = value => {} |
||||
|
export let selected = false |
||||
|
|
||||
|
$: useIcon = !!icon |
||||
|
</script> |
||||
|
|
||||
|
<div class="flatbutton" class:selected on:click={() => onClick(value || text)}> |
||||
|
{#if useIcon} |
||||
|
<i class={icon} /> |
||||
|
{:else} |
||||
|
<span>{text}</span> |
||||
|
{/if} |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.flatbutton { |
||||
|
cursor: pointer; |
||||
|
padding: 5px; |
||||
|
text-align: center; |
||||
|
background: #ffffff; |
||||
|
color: #808192; |
||||
|
border-radius: 4px; |
||||
|
font-family: Roboto; |
||||
|
font-size: 11px; |
||||
|
font-weight: 500; |
||||
|
letter-spacing: 0.11px; |
||||
|
transition: background 0.5s, color 0.5s ease; |
||||
|
} |
||||
|
|
||||
|
.selected { |
||||
|
background: #808192; |
||||
|
color: #ffffff; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,54 @@ |
|||||
|
<script> |
||||
|
import { onMount } from "svelte" |
||||
|
|
||||
|
import FlatButton from "./FlatButton.svelte" |
||||
|
export let buttonProps = [] |
||||
|
export let isMultiSelect = false |
||||
|
export let value = [] |
||||
|
export let initialValue = "" |
||||
|
export let onChange = selected => {} |
||||
|
|
||||
|
onMount(() => { |
||||
|
if (!value && !!initialValue) { |
||||
|
value = initialValue |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
function onButtonClicked(v) { |
||||
|
let val |
||||
|
if (isMultiSelect) { |
||||
|
if (value.includes(v)) { |
||||
|
let idx = value.findIndex(i => i === v) |
||||
|
val = [...value].splice(idx, 1) |
||||
|
} else { |
||||
|
val = [...value, v] |
||||
|
} |
||||
|
} else { |
||||
|
val = v |
||||
|
} |
||||
|
onChange(val) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div class="flatbutton-group"> |
||||
|
{#each buttonProps as props} |
||||
|
<div class="button-container"> |
||||
|
<FlatButton |
||||
|
selected={value.includes(props.value)} |
||||
|
onClick={onButtonClicked} |
||||
|
{...props} /> |
||||
|
</div> |
||||
|
{/each} |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.flatbutton-group { |
||||
|
display: flex; |
||||
|
flex-flow: row nowrap; |
||||
|
} |
||||
|
|
||||
|
.button-container { |
||||
|
flex: 1; |
||||
|
margin: 5px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,33 @@ |
|||||
|
<script> |
||||
|
import { onMount } from "svelte" |
||||
|
export let value = "" |
||||
|
export let onChange = value => {} |
||||
|
export let options = [] |
||||
|
export let initialValue = "" |
||||
|
export let styleBindingProperty = "" |
||||
|
|
||||
|
$: bindOptionToStyle = !!styleBindingProperty |
||||
|
|
||||
|
onMount(() => { |
||||
|
if (!value && !!initialValue) { |
||||
|
value = initialValue |
||||
|
} |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<select |
||||
|
class="uk-select uk-form-small" |
||||
|
{value} |
||||
|
on:change={ev => onChange(ev.target.value)}> |
||||
|
{#each options as { value, label }} |
||||
|
{#if bindOptionToStyle} |
||||
|
<option |
||||
|
style={`${styleBindingProperty}: ${value || label};`} |
||||
|
value={value || label}> |
||||
|
{label} |
||||
|
</option> |
||||
|
{:else} |
||||
|
<option value={value || label}>{label}</option> |
||||
|
{/if} |
||||
|
{/each} |
||||
|
</select> |
||||
@ -0,0 +1,41 @@ |
|||||
|
<script> |
||||
|
export let label = "" |
||||
|
export let control = null |
||||
|
export let value = "" |
||||
|
export let props = {} |
||||
|
export let onChange = () => {} |
||||
|
</script> |
||||
|
|
||||
|
<div class="property-control"> |
||||
|
<div class="label">{label}</div> |
||||
|
<div class="control"> |
||||
|
<svelte:component |
||||
|
this={control} |
||||
|
{value} |
||||
|
on:change={onChange} |
||||
|
{onChange} |
||||
|
{...props} /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.property-control { |
||||
|
display: flex; |
||||
|
flex-flow: row nowrap; |
||||
|
margin: 8px 0px; |
||||
|
} |
||||
|
|
||||
|
.label { |
||||
|
flex: 0 0 50px; |
||||
|
padding: 0px 5px; |
||||
|
font-size: 12px; |
||||
|
font-weight: 500; |
||||
|
letter-spacing: 0.12px; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
.control { |
||||
|
flex: 1; |
||||
|
padding-left: 5px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,101 @@ |
|||||
|
<script> |
||||
|
import { excludeProps } from "./propertyCategories.js" |
||||
|
import PropertyControl from "./PropertyControl.svelte" |
||||
|
|
||||
|
export let name = "" |
||||
|
export let properties = {} |
||||
|
export let componentInstance = {} |
||||
|
export let componentDefinition = {} |
||||
|
export let onPropChanged = () => {} |
||||
|
|
||||
|
export let show = false |
||||
|
let showComponentGroup = false |
||||
|
|
||||
|
const propExistsOnComponentDef = prop => prop in componentDefinition.props |
||||
|
const capitalize = name => name[0].toUpperCase() + name.slice(1) |
||||
|
|
||||
|
function onChange(key, v) { |
||||
|
!!v.target ? onPropChanged(key, v.target.value) : onPropChanged(key, v) |
||||
|
} |
||||
|
|
||||
|
$: { |
||||
|
let res = false |
||||
|
let componentProps = Object.keys(componentDefinition.props) |
||||
|
for (let prop in properties) { |
||||
|
if (componentProps.includes(prop)) { |
||||
|
showComponentGroup = true |
||||
|
} |
||||
|
if (showComponentGroup) break |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$: propertyDefinition = Object.entries(properties) |
||||
|
$: icon = show ? "ri-arrow-down-s-fill" : "ri-arrow-right-s-fill" |
||||
|
</script> |
||||
|
|
||||
|
<!-- {#if showComponentGroup} --> |
||||
|
<div class="property-group-container"> |
||||
|
<div class="property-group-name" on:click={() => (show = !show)}> |
||||
|
<div class="icon"> |
||||
|
<i class={icon} /> |
||||
|
</div> |
||||
|
<div class="name">{capitalize(name)}</div> |
||||
|
</div> |
||||
|
<div class="property-panel" class:show> |
||||
|
|
||||
|
{#each propertyDefinition as [key, definition]} |
||||
|
<!-- {#if propExistsOnComponentDef(key)} --> |
||||
|
<PropertyControl |
||||
|
label={definition.label || capitalize(key)} |
||||
|
control={definition.control} |
||||
|
value={componentInstance[key]} |
||||
|
onChange={value => onChange(key, value)} |
||||
|
props={{ ...excludeProps(definition, ['control']) }} /> |
||||
|
<!-- {/if} --> |
||||
|
{/each} |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- {/if} --> |
||||
|
|
||||
|
<style> |
||||
|
.property-group-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height: auto; |
||||
|
background: #fbfbfb; |
||||
|
margin: 5px; |
||||
|
padding: 5px; |
||||
|
} |
||||
|
|
||||
|
.property-group-name { |
||||
|
cursor: pointer; |
||||
|
flex: 0 0 20px; |
||||
|
display: flex; |
||||
|
flex-flow: row nowrap; |
||||
|
} |
||||
|
|
||||
|
.name { |
||||
|
flex: 1; |
||||
|
text-align: left; |
||||
|
padding-top: 2px; |
||||
|
font-size: 14px; |
||||
|
font-weight: 500; |
||||
|
letter-spacing: 0.14px; |
||||
|
color: #393c44; |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
flex: 0 0 20px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.property-panel { |
||||
|
height: 0px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.show { |
||||
|
overflow: auto; |
||||
|
height: auto; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,240 @@ |
|||||
|
<script> |
||||
|
import ComponentsHierarchy from "./ComponentsHierarchy.svelte" |
||||
|
import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte" |
||||
|
import PageLayout from "./PageLayout.svelte" |
||||
|
import PagesList from "./PagesList.svelte" |
||||
|
import { store } from "builderStore" |
||||
|
import IconButton from "components/common/IconButton.svelte" |
||||
|
import NewScreen from "./NewScreen.svelte" |
||||
|
import CurrentItemPreview from "./CurrentItemPreview.svelte" |
||||
|
import SettingsView from "./SettingsView.svelte" |
||||
|
import PageView from "./PageView.svelte" |
||||
|
import ComponentsPaneSwitcher from "./ComponentsPaneSwitcher.svelte" |
||||
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte" |
||||
|
import { last } from "lodash/fp" |
||||
|
import { AddIcon } from "components/common/Icons" |
||||
|
|
||||
|
let newScreenPicker |
||||
|
let confirmDeleteDialog |
||||
|
let componentToDelete = "" |
||||
|
|
||||
|
const newScreen = () => { |
||||
|
newScreenPicker.show() |
||||
|
} |
||||
|
|
||||
|
let settingsView |
||||
|
const settings = () => { |
||||
|
settingsView.show() |
||||
|
} |
||||
|
|
||||
|
const confirmDeleteComponent = component => { |
||||
|
componentToDelete = component |
||||
|
confirmDeleteDialog.show() |
||||
|
} |
||||
|
|
||||
|
const lastPartOfName = c => (c ? last(c.split("/")) : "") |
||||
|
</script> |
||||
|
|
||||
|
<div class="root"> |
||||
|
|
||||
|
<div class="ui-nav"> |
||||
|
|
||||
|
<div class="pages-list-container"> |
||||
|
<div class="nav-header"> |
||||
|
<span class="navigator-title">Navigator</span> |
||||
|
<div class="border-line" /> |
||||
|
|
||||
|
<span class="components-nav-page">Pages</span> |
||||
|
</div> |
||||
|
|
||||
|
<div class="nav-items-container"> |
||||
|
<PagesList /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="border-line" /> |
||||
|
|
||||
|
<PageLayout layout={$store.pages[$store.currentPageName]} /> |
||||
|
|
||||
|
<div class="border-line" /> |
||||
|
|
||||
|
<div class="components-list-container"> |
||||
|
<div class="nav-group-header"> |
||||
|
<span class="components-nav-header" style="margin-top: 0;"> |
||||
|
Screens |
||||
|
</span> |
||||
|
<div> |
||||
|
<button on:click={newScreen}> |
||||
|
<AddIcon /> |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="nav-items-container"> |
||||
|
<ComponentsHierarchy screens={$store.screens} /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div class="preview-pane"> |
||||
|
<CurrentItemPreview /> |
||||
|
</div> |
||||
|
|
||||
|
{#if $store.currentFrontEndType === 'screen' || $store.currentFrontEndType === 'page'} |
||||
|
<div class="components-pane"> |
||||
|
<ComponentsPaneSwitcher /> |
||||
|
</div> |
||||
|
{/if} |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<NewScreen bind:this={newScreenPicker} /> |
||||
|
<SettingsView bind:this={settingsView} /> |
||||
|
|
||||
|
<ConfirmDialog |
||||
|
bind:this={confirmDeleteDialog} |
||||
|
title="Confirm Delete" |
||||
|
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete)}' component`} |
||||
|
okText="Delete Component" |
||||
|
onOk={() => store.deleteComponent(componentToDelete)} /> |
||||
|
|
||||
|
<style> |
||||
|
button { |
||||
|
cursor: pointer; |
||||
|
outline: none; |
||||
|
border: none; |
||||
|
border-radius: 5px; |
||||
|
width: 20px; |
||||
|
padding-bottom: 10px; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
.root { |
||||
|
display: grid; |
||||
|
grid-template-columns: 275px 1fr 300px; |
||||
|
height: 100%; |
||||
|
width: 100%; |
||||
|
background: #fafafa; |
||||
|
} |
||||
|
|
||||
|
@media only screen and (min-width: 1800px) { |
||||
|
.root { |
||||
|
display: grid; |
||||
|
grid-template-columns: 300px 1fr 300px; |
||||
|
height: 100%; |
||||
|
width: 100%; |
||||
|
background: #fafafa; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ui-nav { |
||||
|
grid-column: 1; |
||||
|
background-color: var(--white); |
||||
|
height: calc(100vh - 49px); |
||||
|
padding: 0; |
||||
|
overflow: scroll; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.preview-pane { |
||||
|
grid-column: 2; |
||||
|
margin: 40px; |
||||
|
background: #fff; |
||||
|
border-radius: 5px; |
||||
|
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05); |
||||
|
} |
||||
|
|
||||
|
.components-pane { |
||||
|
grid-column: 3; |
||||
|
background-color: var(--white); |
||||
|
height: 100vh; |
||||
|
overflow-y: scroll; |
||||
|
} |
||||
|
|
||||
|
.components-nav-page { |
||||
|
font-size: 13px; |
||||
|
color: #000333; |
||||
|
text-transform: uppercase; |
||||
|
padding-left: 20px; |
||||
|
margin-top: 20px; |
||||
|
font-weight: 600; |
||||
|
opacity: 0.4; |
||||
|
letter-spacing: 1px; |
||||
|
} |
||||
|
|
||||
|
.components-nav-header { |
||||
|
font-size: 13px; |
||||
|
color: #000333; |
||||
|
text-transform: uppercase; |
||||
|
margin-top: 20px; |
||||
|
font-weight: 600; |
||||
|
opacity: 0.4; |
||||
|
letter-spacing: 1px; |
||||
|
} |
||||
|
|
||||
|
.nav-header { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
margin-top: 20px; |
||||
|
} |
||||
|
|
||||
|
.nav-items-container { |
||||
|
padding: 1rem 0rem 0rem 0rem; |
||||
|
} |
||||
|
|
||||
|
.nav-group-header { |
||||
|
display: flex; |
||||
|
padding: 0px 20px 0px 20px; |
||||
|
font-size: 0.9rem; |
||||
|
font-weight: bold; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.nav-group-header > div:nth-child(1) { |
||||
|
padding: 0rem 0.5rem 0rem 0rem; |
||||
|
vertical-align: bottom; |
||||
|
grid-column-start: icon; |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
|
||||
|
.nav-group-header > span:nth-child(3) { |
||||
|
margin-left: 5px; |
||||
|
vertical-align: bottom; |
||||
|
grid-column-start: title; |
||||
|
margin-top: auto; |
||||
|
} |
||||
|
|
||||
|
.nav-group-header > div:nth-child(3) { |
||||
|
vertical-align: bottom; |
||||
|
grid-column-start: button; |
||||
|
cursor: pointer; |
||||
|
color: var(--primary75); |
||||
|
} |
||||
|
|
||||
|
.nav-group-header > div:nth-child(3):hover { |
||||
|
color: var(--primary75); |
||||
|
} |
||||
|
|
||||
|
.navigator-title { |
||||
|
font-size: 14px; |
||||
|
color: var(--secondary100); |
||||
|
font-weight: 600; |
||||
|
text-transform: uppercase; |
||||
|
padding: 0 20px 20px 20px; |
||||
|
line-height: 1rem !important; |
||||
|
letter-spacing: 1px; |
||||
|
} |
||||
|
|
||||
|
.border-line { |
||||
|
border-bottom: 1px solid #d8d8d8; |
||||
|
} |
||||
|
|
||||
|
.components-list-container { |
||||
|
padding: 20px 0px 0 0; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,177 @@ |
|||||
|
import Input from "../common/Input.svelte" |
||||
|
import OptionSelect from "./OptionSelect.svelte" |
||||
|
/* |
||||
|
TODO: Allow for default values for all properties |
||||
|
*/ |
||||
|
|
||||
|
export const general = { |
||||
|
text: { control: Input }, |
||||
|
} |
||||
|
|
||||
|
export const layout = { |
||||
|
flexDirection: { |
||||
|
label: "Direction", |
||||
|
control: OptionSelect, |
||||
|
initialValue: "columnReverse", |
||||
|
options: [ |
||||
|
{ label: "row" }, |
||||
|
{ label: "row-reverse", value: "rowReverse" }, |
||||
|
{ label: "column" }, |
||||
|
{ label: "column-reverse", value: "columnReverse" }, |
||||
|
], |
||||
|
}, |
||||
|
justifyContent: { label: "Justify", control: Input }, |
||||
|
alignItems: { label: "Align", control: Input }, |
||||
|
flexWrap: { |
||||
|
label: "Wrap", |
||||
|
control: OptionSelect, |
||||
|
options: [{ label: "wrap" }, { label: "no wrap", value: "noWrap" }], |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
export const spacing = { |
||||
|
padding: { control: Input }, |
||||
|
margin: { control: Input }, |
||||
|
} |
||||
|
|
||||
|
export const size = { |
||||
|
width: { control: Input }, |
||||
|
height: { control: Input }, |
||||
|
minWidth: { label: "Min W", control: Input }, |
||||
|
minHeight: { label: "Min H", control: Input }, |
||||
|
maxWidth: { label: "Max W", control: Input }, |
||||
|
maxHeight: { label: "Max H", control: Input }, |
||||
|
overflow: { |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "visible" }, |
||||
|
{ label: "auto" }, |
||||
|
{ label: "hidden" }, |
||||
|
{ label: "auto" }, |
||||
|
{ label: "scroll" }, |
||||
|
], |
||||
|
}, //custom
|
||||
|
} |
||||
|
|
||||
|
export const position = { |
||||
|
position: { |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "static" }, |
||||
|
{ label: "relative" }, |
||||
|
{ label: "fixed" }, |
||||
|
{ label: "absolute" }, |
||||
|
{ label: "sticky" }, |
||||
|
], |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
export const typography = { |
||||
|
fontFamily: { |
||||
|
label: "Font", |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "initial" }, |
||||
|
{ label: "Times New Roman" }, |
||||
|
{ label: "Georgia" }, |
||||
|
{ label: "Arial" }, |
||||
|
{ label: "Arial Black" }, |
||||
|
{ label: "Comic Sans MS" }, |
||||
|
{ label: "Impact" }, |
||||
|
{ label: "Lucida Sans Unicode" }, |
||||
|
], |
||||
|
styleBindingProperty: "font-family", |
||||
|
}, |
||||
|
fontWeight: { |
||||
|
label: "weight", |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "normal" }, |
||||
|
{ label: "bold" }, |
||||
|
{ label: "bolder" }, |
||||
|
{ label: "lighter" }, |
||||
|
], |
||||
|
}, |
||||
|
fontSize: { label: "size", control: Input }, |
||||
|
lineHeight: { label: "Line H", control: Input }, |
||||
|
color: { |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "black" }, |
||||
|
{ label: "red" }, |
||||
|
{ label: "white" }, |
||||
|
{ label: "blue" }, |
||||
|
{ label: "green" }, |
||||
|
], |
||||
|
}, |
||||
|
textAlign: { |
||||
|
label: "align", |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "initial" }, |
||||
|
{ label: "left" }, |
||||
|
{ label: "right" }, |
||||
|
{ label: "center" }, |
||||
|
{ label: "justify" }, |
||||
|
], |
||||
|
}, //custom
|
||||
|
textTransform: { label: "transform", control: Input }, //custom
|
||||
|
fontStyle: { label: "style", control: Input }, //custom
|
||||
|
} |
||||
|
|
||||
|
export const background = { |
||||
|
backgroundColor: { |
||||
|
label: "Background Color", |
||||
|
control: OptionSelect, |
||||
|
options: [ |
||||
|
{ label: "white" }, |
||||
|
{ label: "red" }, |
||||
|
{ label: "blue" }, |
||||
|
{ label: "green" }, |
||||
|
{ label: "black" }, |
||||
|
], |
||||
|
}, |
||||
|
image: { control: Input }, //custom
|
||||
|
} |
||||
|
|
||||
|
export const border = { |
||||
|
borderRadius: { label: "radius", control: Input }, |
||||
|
borderWidth: { label: "width", control: Input }, //custom
|
||||
|
borderColor: { label: "color", control: Input }, |
||||
|
borderStyle: { label: "style", control: Input }, |
||||
|
} |
||||
|
|
||||
|
export const effects = { |
||||
|
opacity: { control: Input }, |
||||
|
rotate: { control: Input }, |
||||
|
shadow: { control: Input }, |
||||
|
} |
||||
|
|
||||
|
export const transitions = { |
||||
|
property: { control: Input }, |
||||
|
duration: { control: Input }, |
||||
|
ease: { control: Input }, |
||||
|
} |
||||
|
|
||||
|
export const all = { |
||||
|
general, |
||||
|
layout, |
||||
|
spacing, |
||||
|
size, |
||||
|
position, |
||||
|
typography, |
||||
|
background, |
||||
|
border, |
||||
|
effects, |
||||
|
transitions, |
||||
|
} |
||||
|
|
||||
|
export function excludeProps(props, propsToExclude) { |
||||
|
const modifiedProps = {} |
||||
|
for (const prop in props) { |
||||
|
if (!propsToExclude.includes(prop)) { |
||||
|
modifiedProps[prop] = props[prop] |
||||
|
} |
||||
|
} |
||||
|
return modifiedProps |
||||
|
} |
||||
Loading…
Reference in new issue