Stable property panel

This commit is contained in:
Conor_Mack 2020-05-21 14:28:32 +01:00
parent 017ac7aced
commit facd99f58a
10 changed files with 122 additions and 77 deletions

View File

@ -79,7 +79,8 @@
"rollup-plugin-svelte": "^5.0.3", "rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^4.0.4", "rollup-plugin-terser": "^4.0.4",
"rollup-plugin-url": "^2.2.2", "rollup-plugin-url": "^2.2.2",
"svelte": "^3.0.0" "svelte": "^3.0.0",
"svelte-color-picker": "^1.0.7"
}, },
"gitHead": "115189f72a850bfb52b65ec61d932531bf327072" "gitHead": "115189f72a850bfb52b65ec61d932531bf327072"
} }

View File

@ -121,7 +121,9 @@ export const generate_css = style => {
return (str += `${key}: ${value};\n`) return (str += `${key}: ${value};\n`)
} }
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
return (str += `${key}: ${value.map(v => `${v}px`).join(" ")};\n`) return (str += `${key}: ${value
.map(v => (!/px$/.test(v) ? `${v}px` : v))
.join(" ")};\n`)
} }
}, "") }, "")

View File

@ -1,13 +1,78 @@
<script> <script>
import { onMount, beforeUpdate, afterUpdate } from "svelte" import { onMount } from "svelte"
import { HsvPicker } from "svelte-color-picker"
export let value = null // export let initialValue = "#ffffff"
export let onChange = () => {} export let onChange = color => {}
export let swatches = [] export let open = false
let value = "#ffffff"
let picker let _justMounted = true //see onColorChange
let cp = null let pickerHeight = 275
let colorPreview
let pickerTopPosition = null
function rbgaToHexa({ r, g, b, a }) {
r = r.toString(16)
g = g.toString(16)
b = b.toString(16)
a = Math.round(a * 255).toString(16)
if (r.length == 1) r = "0" + r
if (g.length == 1) g = "0" + g
if (b.length == 1) b = "0" + b
if (a.length == 1) a = "0" + a
return "#" + r + g + b + a
}
function onColourChange(rgba) {
value = rbgaToHexa(rgba.detail)
//Hack: so that color change doesn't fire onMount
if (!_justMounted) {
// onChange(value)
}
_justMounted = false
}
function toggleColorpicker(isOpen) {
if (isOpen) {
const {
y: previewYPosition,
height: previewHeight,
} = colorPreview.getBoundingClientRect()
let wiggleRoom = window.innerHeight - previewYPosition
let displayTop = wiggleRoom < pickerHeight
if (displayTop) {
pickerTopPosition = previewYPosition - (pickerHeight - window.scrollY)
} else {
pickerTopPosition = null
}
}
open = isOpen
}
$: style = open ? "display: block;" : "display: none;"
$: pickerStyle = pickerTopPosition ? `top: ${pickerTopPosition}px;` : ""
</script>
<div
bind:this={colorPreview}
on:click={() => toggleColorpicker(true)}
class="color-preview"
style={`background: ${value}`} />
<div class="colorpicker" {style}>
<div class="overlay" on:click|self={() => toggleColorpicker(false)} />
<div class="cp" style={pickerStyle}>
<HsvPicker on:colorChange={onColourChange} startColor={value} />
</div>
</div>
<!--
OLD LOCAL STORAGE OPTIONS. INCLUDING FOR ADDING LATER
function getRecentColors() { function getRecentColors() {
let colorStore = localStorage.getItem("bb:recentColors") let colorStore = localStorage.getItem("bb:recentColors")
if (!!colorStore) { if (!!colorStore) {
@ -25,44 +90,27 @@
picker.addSwatch(color) picker.addSwatch(color)
localStorage.setItem("bb:recentColors", JSON.stringify(swatches)) localStorage.setItem("bb:recentColors", JSON.stringify(swatches))
} }
} -->
<style>
.overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* background: rgba(5, 5, 5, 0.25); */
} }
function createPicker() { .cp {
picker = Pickr.create({ position: absolute;
el: cp, right: 25px;
theme: "nano",
default: value || "#000000",
swatches,
closeWithKey: "Escape",
components: {
preview: true,
opacity: true,
hue: true,
interaction: {
hex: true,
rgba: true,
input: true,
save: true,
},
},
})
} }
.color-preview {
afterUpdate(() => { height: 30px;
picker.setColor(value) width: 100%;
}) margin: 5px;
cursor: pointer;
onMount(() => { border: 1px solid gainsboro;
getRecentColors()
createPicker()
return () => {
picker.destroyAndRemove()
picker = null
} }
}) </style>
</script>
<div bind:this={cp} class="color-picker" />

View File

@ -3,13 +3,15 @@
export let meta = [] export let meta = []
export let label = "" export let label = ""
export let values = [] export let value = [0, 0, 0, 0]
export let type = "number" export let type = "number"
export let onChange = () => {} export let onChange = () => {}
let _values = values.map(v => v) function handleChange(val, idx) {
value.splice(idx, 1, val)
// $: onChange(_values) value = value
onChange(value)
}
</script> </script>
<div class="input-container"> <div class="input-container">
@ -19,8 +21,8 @@
<input <input
{type} {type}
placeholder={placeholder || ''} placeholder={placeholder || ''}
value={values[i]} value={value[i] === 0 ? '' : value[i]}
on:input={e => (_values[i] = e.target.value)} /> on:change={e => handleChange(e.target.value || 0, i)} />
{/each} {/each}
</div> </div>
</div> </div>
@ -36,8 +38,6 @@
.inputs { .inputs {
flex: 1; flex: 1;
/* display: flex;
justify-content: space-between; */
} }
input { input {

View File

@ -4,21 +4,22 @@
export let label = "" export let label = ""
export let control = null export let control = null
export let key = "" export let key = ""
export let value = "" export let value
export let props = {} export let props = {}
export let onChange = () => {} export let onChange = () => {}
function handleChange(key, v) { function handleChange(key, v) {
if (v.target) { if (v.target) {
let val = props.valueType ? v.target[props.valueType] : v.target.value let val = props.valueKey ? v.target[props.valueKey] : v.target.value
onChange(key, val) onChange(key, val)
} else { } else {
onChange(key, v) onChange(key, v)
} }
} }
const handleValueType = value => //Incase the component has a different value key name
props.valueType ? { [props.valueType]: value } : { value } const handlevalueKey = value =>
props.valueKey ? { [props.valueKey]: value } : { value }
</script> </script>
<div class="property-control"> <div class="property-control">
@ -26,7 +27,7 @@
<div class="control"> <div class="control">
<svelte:component <svelte:component
this={control} this={control}
{...handleValueType(value)} {...handlevalueKey(value)}
on:change={val => handleChange(key, val)} on:change={val => handleChange(key, val)}
onChange={val => handleChange(key, val)} onChange={val => handleChange(key, val)}
{...props} /> {...props} />

View File

@ -1,6 +1,7 @@
<script> <script>
import PropertyControl from "./PropertyControl.svelte" import PropertyControl from "./PropertyControl.svelte"
import InputGroup from "../common/Inputs/InputGroup.svelte" import InputGroup from "../common/Inputs/InputGroup.svelte"
import Colorpicker from "../common/Colorpicker.svelte"
import { excludeProps } from "./propertyCategories.js" import { excludeProps } from "./propertyCategories.js"
export let panelDefinition = [] export let panelDefinition = []
@ -15,6 +16,8 @@
} }
</script> </script>
<Colorpicker />
{#if panelDefinition.length > 0} {#if panelDefinition.length > 0}
{#each panelDefinition as definition} {#each panelDefinition as definition}
{#if propExistsOnComponentDef(definition.key)} {#if propExistsOnComponentDef(definition.key)}

View File

@ -1,6 +1,7 @@
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 Colorpicker from "../common/Colorpicker.svelte"
/* /*
TODO: Allow for default values for all properties TODO: Allow for default values for all properties
*/ */
@ -101,8 +102,7 @@ export const typography = [
{ {
label: "Color", label: "Color",
key: "color", key: "color",
control: OptionSelect, control: Colorpicker,
options: ["black", "red", "white", "blue", "green"],
}, },
{ {
label: "align", label: "align",
@ -118,14 +118,7 @@ export const background = [
{ {
label: "Background", label: "Background",
key: "background", key: "background",
control: OptionSelect, control: Colorpicker,
options: [
{ label: "white" },
{ label: "red" },
{ label: "blue" },
{ label: "green" },
{ label: "black" },
],
}, },
{ label: "Image", key: "image", control: Input }, //custom { label: "Image", key: "image", control: Input }, //custom
] ]
@ -133,7 +126,7 @@ export const background = [
export const border = [ export const border = [
{ label: "Radius", key: "border-radius", control: Input }, { label: "Radius", key: "border-radius", control: Input },
{ label: "Width", key: "border-width", control: Input }, //custom { label: "Width", key: "border-width", control: Input }, //custom
{ label: "Color", key: "border-color", control: Input }, { label: "Color", key: "border-color", control: Colorpicker },
{ label: "Style", key: "border-style", control: Input }, { label: "Style", key: "border-style", control: Input },
] ]

View File

@ -189,7 +189,7 @@ export default {
{ {
label: "Disabled", label: "Disabled",
key: "disabled", key: "disabled",
valueType: "checked", valueKey: "checked",
control: Checkbox, control: Checkbox,
}, },
] ]
@ -219,7 +219,7 @@ export default {
{ {
label: "Open New Tab", label: "Open New Tab",
key: "openInNewTab", key: "openInNewTab",
valueType: "checked", valueKey: "checked",
control: Checkbox, control: Checkbox,
}, },
], ],

File diff suppressed because one or more lines are too long

View File

@ -17,12 +17,10 @@
<button <button
bind:this={theButton} bind:this={theButton}
class="{className} class={className}
disabled={disabled || false} disabled={disabled || false}
on:click={clickHandler}> on:click={clickHandler}>
{#if !_bb.props._children || _bb.props._children.length === 0} {#if !_bb.props._children || _bb.props._children.length === 0}{text}{/if}
{text}
{/if}
</button> </button>
<style> <style>