Property panel updates

This commit is contained in:
Conor_Mack 2020-06-01 16:31:58 +01:00
parent 91b88ecad7
commit 93ab8659ed
8 changed files with 888 additions and 903 deletions

View File

@ -1,54 +1,42 @@
export const generate_screen_css = component_arr => { export const generate_screen_css = (component_arr) => {
let styles = "" let styles = '';
for (const { _styles, _id, _children, _component } of component_arr) { for (const { _styles, _id, _children, _component } of component_arr) {
let [componentName] = _component.match(/[a-z]*$/) let [ componentName ] = _component.match(/[a-z]*$/);
Object.keys(_styles).forEach(selector => { Object.keys(_styles).forEach((selector) => {
const cssString = generate_css(_styles[selector]) const cssString = generate_css(_styles[selector]);
if (cssString) { if (cssString) {
styles += apply_class(_id, componentName, cssString, selector) styles += apply_class(_id, componentName, cssString, selector);
} }
}) });
if (_children && _children.length) { if (_children && _children.length) {
styles += generate_screen_css(_children) + "\n" styles += generate_screen_css(_children) + '\n';
} }
} }
return styles.trim() return styles.trim();
} };
export const generate_css = style => { export const generate_css = (style) => {
let cssString = Object.entries(style).reduce((str, [key, value]) => { let cssString = Object.entries(style).reduce((str, [ key, value ]) => {
//TODO Handle arrays and objects here also //TODO Handle arrays and objects here also
if (typeof value === "string") { if (typeof value === 'string') {
if (value) { if (value) {
return (str += `${key}: ${value};\n`) return (str += `${key}: ${value};\n`);
} }
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
if (value.length > 0 && !value.every(v => v === "")) { if (value.length > 0 && !value.every((v) => v === '')) {
return (str += `${key}: ${value return (str += `${key}: ${value.join(' ')};\n`);
.map(generate_array_styles) }
.join(" ")};\n`) }
} }, '');
}
}, "")
return (cssString || "").trim() return (cssString || '').trim();
} };
export const generate_array_styles = item => { export const apply_class = (id, name = 'element', styles, selector) => {
let safeItem = item === "" ? 0 : item if (selector === 'normal') {
let hasPx = new RegExp("px$") return `.${name}-${id} {\n${styles}\n}`;
if (!hasPx.test(safeItem)) { } else {
return `${safeItem}px` let sel = selector === 'selected' ? '::selection' : `:${selector}`;
} else { return `.${name}-${id}${sel} {\n${styles}\n}`;
return safeItem }
} };
}
export const apply_class = (id, name = "element", styles, selector) => {
if (selector === "normal") {
return `.${name}-${id} {\n${styles}\n}`
} else {
let sel = selector === "selected" ? "::selection" : `:${selector}`
return `.${name}-${id}${sel} {\n${styles}\n}`
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,20 @@
<script> <script>
import {buildStyle} from "../../helpers.js" import {onMount} from "svelte"
import { buildStyle } from "../../helpers.js"
export let value = "" export let value = ""
export let textAlign = "left" export let textAlign = "left"
export let width = "160px" export let width = "160px"
export let placeholder = "" export let placeholder = ""
let centerPlaceholder = textAlign === "center"
let style = buildStyle({ width, textAlign }) let style = buildStyle({ width, textAlign })
</script> </script>
<input type="text" {placeholder} {style} on:change bind:value /> <input class:centerPlaceholder type="text" {placeholder} {style} on:change bind:value />
<style> <style>
input { input {
width: 32px; width: 32px;
height: 32px; height: 32px;
font-size: 12px; font-size: 12px;
@ -24,10 +27,13 @@
border: 1px solid var(--grey); border: 1px solid var(--grey);
border-radius: 2px; border-radius: 2px;
outline: none; outline: none;
float: right;
} }
input::placeholder { input::placeholder {
text-align: left;
}
.centerPlaceholder::placeholder {
text-align: center; text-align: center;
} }
</style> </style>

View File

@ -5,40 +5,41 @@
export let meta = [] export let meta = []
export let label = "" export let label = ""
export let value = ["0", "0", "0", "0"] export let value = ["0", "0", "0", "0"]
export let type = "number" export let suffix = ""
export let onChange = () => {} export let onChange = () => {}
function handleChange(val, idx) { function handleChange(val, idx) {
value.splice(idx, 1, val) value.splice(idx, 1, suffix ? val + suffix : val)
value = value value = value
console.log("IDX",idx) let _value = value.map(v => (!v.endsWith(suffix) ? v + suffix : v))
let _value = value.map(v => !/px$/.test(v) ? `${v}px` : v)
onChange(_value) onChange(_value)
} }
$: displayValues = value.map(v => v.toString().replace(/px$/, "")) $: displayValues = value
? value.map(v => v.replace(new RegExp(`${suffix}$`), ""))
: []
</script> </script>
<div class="input-container"> <div class="input-container">
<div class="label">{label}</div> <div class="label">{label}</div>
<div class="inputs"> <div class="inputs-group">
{#each meta as { placeholder }, i} {#each meta as m, i}
<Input
<Input width="32px" textAlign="center" placeholder={placeholder || ""} value={!displayValues || displayValues[i] === 0 ? '' : displayValues[i]} on:change={e => handleChange(e.target.value || 0, i)} /> width="32px"
textAlign="center"
placeholder={m.placeholder || ''}
value={!displayValues || displayValues[i] === '0' ? '' : displayValues[i]}
on:change={e => handleChange(e.target.value || 0, i)} />
{/each} {/each}
</div> </div>
</div> </div>
<style> <style>
.label { .label {
flex: 0; flex: 0;
} }
.inputs { .inputs-group {
flex: 1; flex: 1;
} }
</style> </style>

View File

@ -3,7 +3,7 @@
export let value = "" export let value = ""
export let text = "" export let text = ""
export let icon = "" export let icon = ""
export let padding = "8px 2px;" export let padding = "8px 5px;"
export let onClick = value => {} export let onClick = value => {}
export let selected = false export let selected = false
export let fontWeight = "" export let fontWeight = ""

View File

@ -28,9 +28,9 @@
onChange(val) onChange(val)
} }
const checkSelected = val => isMultiSelect ? value.includes(val) : value === val const checkSelected = val =>
isMultiSelect ? value.includes(val) : value === val
$: console.log("VALUE",value)
</script> </script>
<div class="flatbutton-group"> <div class="flatbutton-group">

View File

@ -144,6 +144,7 @@
width: 160px; width: 160px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;
font-size: 12px;
} }
.bb-select-anchor { .bb-select-anchor {
@ -153,6 +154,7 @@
background-color: #f2f2f2; background-color: #f2f2f2;
border-radius: 2px; border-radius: 2px;
border: 1px solid var(--grey-dark); border: 1px solid var(--grey-dark);
align-items: center;
} }
.bb-select-anchor > span { .bb-select-anchor > span {

View File

@ -1,365 +1,407 @@
import Input from "../common/Input.svelte" import Input from '../common/Input.svelte';
import OptionSelect from "./OptionSelect.svelte" import OptionSelect from './OptionSelect.svelte';
import InputGroup from "../common/Inputs/InputGroup.svelte" import InputGroup from '../common/Inputs/InputGroup.svelte';
import FlatButtonGroup from "./FlatButtonGroup.svelte" import FlatButtonGroup from './FlatButtonGroup.svelte';
// import Colorpicker from "../common/Colorpicker.svelte" // import Colorpicker from "../common/Colorpicker.svelte"
/* /*
TODO: Allow for default values for all properties 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: "Flex", initialValue: 'Flex',
options: [ options: [ { label: 'Flex', value: 'flex' }, { label: 'Inline Flex', value: 'inline-flex' } ]
{ label: "Flex", value: "flex" }, },
{ label: "Inline Flex", value: "inline-flex" }, {
], label: 'Direction',
}, key: 'flex-direction',
{ control: FlatButtonGroup,
label: "Direction", buttonProps: [
key: "flex-direction", { icon: 'ri-arrow-right-line', padding: '0px 5px', value: 'row' },
control: FlatButtonGroup, { icon: 'ri-arrow-left-line', padding: '0px 5px', value: 'rowReverse' },
buttonProps: [ { icon: 'ri-arrow-down-line', padding: '0px 5px', value: 'column' },
{ icon: "ri-arrow-right-line", padding: "4px 8px", value: "row" }, {
{ icon: "ri-arrow-left-line", padding: "4px 8px", value: "rowReverse" }, icon: 'ri-arrow-up-line',
{ icon: "ri-arrow-down-line", padding: "4px 8px", value: "column" }, padding: '0px 5px',
{ value: 'columnReverse'
icon: "ri-arrow-up-line", }
padding: "4px 8px", ]
value: "columnReverse", },
}, {
], label: 'Justify',
}, key: 'justify-content',
{ control: OptionSelect,
label: "Justify", initialValue: 'Flex Start',
key: "justify-content", options: [
control: OptionSelect, { label: 'Flex Start', value: 'flex-start' },
initialValue: "Flex Start", { label: 'Flex End', value: 'flex-end' },
options: [ { label: 'Center', value: 'center' },
{ label: "Flex Start", value: "flex-start" }, { label: 'Space Between', value: 'space-between' },
{ label: "Flex End", value: "flex-end" }, { label: 'Space Around', value: 'space-around' },
{ label: "Center", value: "center" }, { label: 'Space Evenly', value: 'space-evenly' }
{ label: "Space Between", value: "space-between" }, ]
{ label: "Space Around", value: "space-around" }, },
{ label: "Space Evenly", value: "space-evenly" }, {
], label: 'Align',
}, key: 'align-items',
{ control: OptionSelect,
label: "Align", initialValue: 'Flex Start',
key: "align-items", options: [
control: OptionSelect, { label: 'Flex Start', value: 'flex-start' },
initialValue: "Flex Start", { label: 'Flex End', value: 'flex-end' },
options: [ { label: 'Center', value: 'center' },
{ label: "Flex Start", value: "flex-start" }, { label: 'Baseline', value: 'baseline' },
{ label: "Flex End", value: "flex-end" }, { label: 'Stretch', value: 'stretch' }
{ label: "Center", value: "center" }, ]
{ label: "Baseline", value: "baseline" }, },
{ label: "Stretch", value: "stretch" }, {
], label: 'Wrap',
}, key: 'flex-wrap',
{ control: OptionSelect,
label: "Wrap", options: [ { label: 'wrap', value: 'wrap' }, { label: 'no wrap', value: 'noWrap' } ]
key: "flex-wrap", }
control: OptionSelect, ];
options: [
{ label: "wrap", value: "wrap" },
{ label: "no wrap", value: "noWrap" },
],
},
]
const spacingMeta = [ const spacingMeta = [ { placeholder: 'T' }, { placeholder: 'R' }, { placeholder: 'B' }, { placeholder: 'L' } ];
{ placeholder: "&#8593;" },
{ placeholder: "&#8594;" },
{ placeholder: "&#8595;" },
{ placeholder: "&#8592;" },
]
export const spacing = [ export const spacing = [
{ label: "Margin", key: "margin", control: InputGroup, meta: spacingMeta }, {
{ label: 'Margin',
label: "Padding", key: 'margin',
key: "padding", control: InputGroup,
control: InputGroup, meta: spacingMeta,
meta: spacingMeta, suffix: 'px',
}, defaultValue: [ '0', '0', '0', '0' ]
] },
{
label: 'Padding',
key: 'padding',
control: InputGroup,
meta: spacingMeta,
suffix: 'px',
defaultValue: [ '0', '0', '0', '0' ]
}
];
export const size = [ export const size = [
{ {
label: "Width", label: 'Width',
key: "width", key: 'width',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Height", label: 'Height',
key: "height", key: 'height',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Min W", label: 'Min W',
key: "min-width", key: 'min-width',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Min H", label: 'Min H',
key: "min-height", key: 'min-height',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Max W", label: 'Max W',
key: "max-width", key: 'max-width',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Max H", label: 'Max H',
key: "max-height", key: 'max-height',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, }
] ];
export const position = [ export const position = [
{ {
label: "Position", label: 'Position',
key: "position", key: 'position',
control: OptionSelect, control: OptionSelect,
initialValue: "Wrap", initialValue: 'Wrap',
options: [ options: [
{ label: "Static", value: "static" }, { label: 'Static', value: 'static' },
{ label: "Relative", value: "relative" }, { label: 'Relative', value: 'relative' },
{ label: "Fixed", value: "fixed" }, { label: 'Fixed', value: 'fixed' },
{ label: "Absolute", value: "absolute" }, { label: 'Absolute', value: 'absolute' },
{ label: "Sticky", value: "sticky" }, { label: 'Sticky', value: 'sticky' }
], ]
}, },
{ {
label: "Top", label: 'Top',
key: "top", key: 'top',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Right", label: 'Right',
key: "right", key: 'right',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Bottom", label: 'Bottom',
key: "bottom", key: 'bottom',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Left", label: 'Left',
key: "left", key: 'left',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Z-index", label: 'Z-index',
key: "z-index", key: 'z-index',
control: Input, control: Input,
placeholder: "Num", placeholder: 'num',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, }
] ];
export const typography = [ export const typography = [
{ {
label: "Font", label: 'Font',
key: "font-family", key: 'font-family',
control: OptionSelect, control: OptionSelect,
defaultValue: "initial", defaultValue: 'initial',
options: [ options: [
"initial", 'initial',
"Arial", 'Arial',
"Arial Black", 'Arial Black',
"Cursive", 'Cursive',
"Courier", 'Courier',
"Comic Sans MS", 'Comic Sans MS',
"Helvetica", 'Helvetica',
"Impact", 'Impact',
"Inter", 'Inter',
"Lucida Sans Unicode", 'Lucida Sans Unicode',
"Open Sans", 'Open Sans',
"Playfair", 'Playfair',
"Roboto", 'Roboto',
"Roboto Mono", 'Roboto Mono',
"Times New Roman", 'Times New Roman',
"Verdana", 'Verdana'
], ],
styleBindingProperty: "font-family", styleBindingProperty: 'font-family'
}, },
{ {
label: "Weight", label: 'Weight',
key: "font-weight", key: 'font-weight',
control: OptionSelect, control: OptionSelect,
options: ["normal", "bold", "bolder", "lighter"], options: [ 'normal', 'bold', 'bolder', 'lighter' ]
}, },
{ {
label: "size", label: 'size',
key: "font-size", key: 'font-size',
defaultValue: "", defaultValue: '',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Line H", label: 'Line H',
key: "line-height", key: 'line-height',
control: Input, control: Input,
placeholder: "lh", placeholder: 'lh',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Color", label: 'Color',
key: "color", key: 'color',
control: Input, control: Input,
}, placeholder: "hex",
{ },
label: "align", {
key: "text-align", label: 'align',
control: FlatButtonGroup, key: 'text-align',
buttonProps: [ control: FlatButtonGroup,
{ icon: "ri-align-left", padding: "4px 8px", value: "left" }, buttonProps: [
{ icon: "ri-align-center", padding: "4px 8px", value: "center" }, { icon: 'ri-align-left', padding: '0px 5px', value: 'left' },
{ icon: "ri-align-right", padding: "4px 8px", value: "right" }, { icon: 'ri-align-center', padding: '0px 5px', value: 'center' },
{ icon: "ri-align-justify", padding: "4px 8px", value: "justify" }, { icon: 'ri-align-right', padding: '0px 5px', value: 'right' },
], { icon: 'ri-align-justify', padding: '0px 5px', value: 'justify' }
}, ]
{ },
label: "transform", {
key: "text-transform", label: 'transform',
control: FlatButtonGroup, key: 'text-transform',
buttonProps: [ control: FlatButtonGroup,
{ text: "BB", padding: "4px 8px", fontWeight: 500, value: "uppercase" }, buttonProps: [
{ text: "Bb", padding: "4px 8px", fontWeight: 500, value: "capitalize" }, { text: 'BB', padding: '0px 5px', fontWeight: 500, value: 'uppercase' },
{ text: "bb", padding: "4px 8px", fontWeight: 500, value: "lowercase" }, { text: 'Bb', padding: '0px 5px', fontWeight: 500, value: 'capitalize' },
{ { text: 'bb', padding: '0px 5px', fontWeight: 500, value: 'lowercase' },
text: "&times;", {
padding: "4px 8px", text: '&times;',
fontWeight: 500, padding: '0px 5px',
value: "none", fontWeight: 500,
}, value: 'none'
], }
}, ]
{ label: "style", key: "font-style", control: Input }, },
] { label: 'style', key: 'font-style', control: Input }
];
export const background = [ export const background = [
{
label: 'Background',
key: 'background',
control: Input,
},
{ {
label: "Background", label: "Image",
key: "background", key: "background-image",
control: Input, control: Input,
placeholder: "src",
}, },
{ label: "Image", key: "image", control: Input }, //custom ];
]
export const border = [ export const border = [
{ label: "Radius", key: "border-radius", control: Input }, {
{ label: "Width", key: "border-width", control: Input }, //custom label: 'Radius',
{ key: 'border-radius',
label: "Color", control: Input,
key: "border-color", width: '48px',
control: Input, placeholder: 'px',
}, textAlign: 'center'
{ },
label: "Style", {
key: "border-style", label: 'Width',
control: OptionSelect, key: 'border-width',
options: [ control: Input,
"none", width: '48px',
"hidden", placeholder: 'px',
"dotted", textAlign: 'center'
"dashed", }, //custom
"solid", {
"double", label: 'Color',
"groove", key: 'border-color',
"ridge", control: Input
"inset", },
"outset", {
], label: 'Style',
}, key: 'border-style',
] control: OptionSelect,
options: [ 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset' ]
}
];
export const effects = [ export const effects = [
{ label: "Opacity", key: "opacity", control: Input }, {
label: 'Opacity',
key: 'opacity',
control: Input,
width: '48px',
textAlign: 'center',
placeholder: '%'
},
{
label: 'Rotate',
key: 'transform',
control: Input,
width: '48px',
textAlign: 'center',
placeholder: 'deg'
}, //needs special control
{ {
label: "Rotate", label: "Shadow",
key: "transform", key: "box-shadow",
control: OptionSelect, control: InputGroup,
options: [ meta: [{ placeholder: "X" }, { placeholder: "Y" }, { placeholder: "B" }],
{ label: "None", value: "rotate(0deg)" }, },
{ label: "45 degrees", value: "rotate(45deg)" }, ];
{ label: "90 degrees", value: "rotate(90deg)" },
{ label: "135 degrees", value: "rotate(135deg)" },
{ label: "180 degrees", value: "rotate(180deg)" },
{ label: "225 degrees", value: "rotate(225deg)" },
{ label: "270 degrees", value: "rotate(270deg)" },
{ label: "315 degrees", value: "rotate(315deg)" },
{ label: "360 degrees", value: "rotate(360deg)" },
],
}, //needs special control
{ label: "Shadow", key: "box-shadow", control: Input },
]
export const transitions = [ export const transitions = [
{ label: "Property", key: "transition-property", control: Input }, {
{ label: "Duration", key: "transition-timing-function", control: Input }, label: 'Property',
{ label: "Ease", key: "transition-ease", control: Input }, key: 'transition-property',
] control: OptionSelect,
options: [
'None',
'All',
'Background Color',
'Color',
'Font Size',
'Font Weight',
'Height',
'Margin',
'Opacity',
'Padding',
'Rotate',
'Shadow',
'Width'
]
},
{
label: 'Duration',
key: 'transition-timing-function',
control: Input,
width: '48px',
textAlign: 'center',
placeholder: 'sec'
},
{
label: 'Ease',
key: 'transition-ease',
control: OptionSelect,
options: [ 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out' ]
}
];
export const all = { export const all = {
layout, layout,
spacing, spacing,
size, size,
position, position,
typography, typography,
background, background,
border, border,
effects, effects,
transitions, transitions
} };
export function excludeProps(props, propsToExclude) { export function excludeProps(props, propsToExclude) {
const modifiedProps = {} const modifiedProps = {};
for (const prop in props) { for (const prop in props) {
if (!propsToExclude.includes(prop)) { if (!propsToExclude.includes(prop)) {
modifiedProps[prop] = props[prop] modifiedProps[prop] = props[prop];
} }
} }
return modifiedProps return modifiedProps;
} }