Stable property panel

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

View File

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

View File

@ -121,7 +121,9 @@ export const generate_css = style => {
return (str += `${key}: ${value};\n`)
}
} 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>
import { onMount, beforeUpdate, afterUpdate } from "svelte"
import { onMount } from "svelte"
import { HsvPicker } from "svelte-color-picker"
export let value = null
export let onChange = () => {}
export let swatches = []
// export let initialValue = "#ffffff"
export let onChange = color => {}
export let open = false
let value = "#ffffff"
let picker
let cp = null
let _justMounted = true //see onColorChange
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() {
let colorStore = localStorage.getItem("bb:recentColors")
if (!!colorStore) {
@ -25,44 +90,27 @@
picker.addSwatch(color)
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() {
picker = Pickr.create({
el: cp,
theme: "nano",
default: value || "#000000",
swatches,
closeWithKey: "Escape",
components: {
preview: true,
opacity: true,
hue: true,
interaction: {
hex: true,
rgba: true,
input: true,
save: true,
},
},
})
.cp {
position: absolute;
right: 25px;
}
afterUpdate(() => {
picker.setColor(value)
})
onMount(() => {
getRecentColors()
createPicker()
return () => {
picker.destroyAndRemove()
picker = null
.color-preview {
height: 30px;
width: 100%;
margin: 5px;
cursor: pointer;
border: 1px solid gainsboro;
}
})
</script>
<div bind:this={cp} class="color-picker" />
</style>

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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