Stable property panel
This commit is contained in:
parent
017ac7aced
commit
facd99f58a
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`)
|
||||||
}
|
}
|
||||||
}, "")
|
}, "")
|
||||||
|
|
||||||
|
|
|
@ -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()
|
</style>
|
||||||
return () => {
|
|
||||||
picker.destroyAndRemove()
|
|
||||||
picker = null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div bind:this={cp} class="color-picker" />
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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)}
|
||||||
|
|
|
@ -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 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue