Add color picker component and tidy up style options
This commit is contained in:
parent
817dc7b3cf
commit
361d27cb08
|
@ -0,0 +1,218 @@
|
|||
<script>
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import "@spectrum-css/popover/dist/index-vars.css"
|
||||
import clickOutside from "../Actions/click_outside"
|
||||
import { fly } from "svelte/transition"
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
import Input from "../Form/Input.svelte"
|
||||
import { capitalise } from "helpers"
|
||||
|
||||
export let value
|
||||
|
||||
let open = false
|
||||
|
||||
$: color = value || "transparent"
|
||||
$: customValue = getCustomValue(value)
|
||||
$: checkColor = getCheckColor(value)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const categories = [
|
||||
{
|
||||
label: "Grays",
|
||||
colors: [
|
||||
"white",
|
||||
"gray-50",
|
||||
"gray-75",
|
||||
"gray-100",
|
||||
"gray-200",
|
||||
"gray-300",
|
||||
"gray-400",
|
||||
"gray-500",
|
||||
"gray-600",
|
||||
"gray-700",
|
||||
"gray-800",
|
||||
"gray-900",
|
||||
"black",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Colors",
|
||||
colors: [
|
||||
"red-400",
|
||||
"orange-400",
|
||||
"yellow-400",
|
||||
"green-400",
|
||||
"seafoam-400",
|
||||
"blue-400",
|
||||
"indigo-400",
|
||||
"magenta-400",
|
||||
|
||||
"red-500",
|
||||
"orange-500",
|
||||
"yellow-500",
|
||||
"green-500",
|
||||
"seafoam-500",
|
||||
"blue-500",
|
||||
"indigo-500",
|
||||
"magenta-500",
|
||||
|
||||
"red-600",
|
||||
"orange-600",
|
||||
"yellow-600",
|
||||
"green-600",
|
||||
"seafoam-600",
|
||||
"blue-600",
|
||||
"indigo-600",
|
||||
"magenta-600",
|
||||
|
||||
"red-700",
|
||||
"orange-700",
|
||||
"yellow-700",
|
||||
"green-700",
|
||||
"seafoam-700",
|
||||
"blue-700",
|
||||
"indigo-700",
|
||||
"magenta-700",
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const onChange = value => {
|
||||
dispatch("change", value)
|
||||
open = false
|
||||
}
|
||||
|
||||
const getCustomValue = value => {
|
||||
if (!value) {
|
||||
return value
|
||||
}
|
||||
let found = false
|
||||
const comparisonValue = value.substring(35, value.length - 1)
|
||||
for (let category of categories) {
|
||||
found = category.colors.includes(comparisonValue)
|
||||
if (found) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return found ? null : value
|
||||
}
|
||||
|
||||
const prettyPrint = color => {
|
||||
return capitalise(color.split("-").join(" "))
|
||||
}
|
||||
|
||||
const getCheckColor = value => {
|
||||
return /^.*(white|(gray-(50|75|100|200|300|400|500)))\)$/.test(value)
|
||||
? "black"
|
||||
: "white"
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="preview"
|
||||
style="background: {color};"
|
||||
on:click={() => (open = true)}
|
||||
/>
|
||||
{#if open}
|
||||
<div
|
||||
use:clickOutside={() => (open = false)}
|
||||
transition:fly={{ y: -20, duration: 200 }}
|
||||
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
|
||||
>
|
||||
{#each categories as category}
|
||||
<div class="category">
|
||||
<div class="heading">{category.label}</div>
|
||||
<div class="colors">
|
||||
{#each category.colors as color}
|
||||
<div
|
||||
on:click={() => {
|
||||
onChange(`var(--spectrum-global-color-static-${color})`)
|
||||
}}
|
||||
class="color"
|
||||
style="background: var(--spectrum-global-color-static-{color}); color: {checkColor};"
|
||||
title={prettyPrint(color)}
|
||||
>
|
||||
{#if value === `var(--spectrum-global-color-static-${color})`}
|
||||
<Icon name="Checkmark" size="S" />
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="category category--custom">
|
||||
<div class="heading">Custom</div>
|
||||
<div class="custom">
|
||||
<Input
|
||||
updateOnChange={false}
|
||||
quiet
|
||||
placeholder="Hex, RGB, HSL..."
|
||||
value={customValue}
|
||||
on:change
|
||||
/>
|
||||
<Icon size="S" name="Close" hoverable on:click={() => onChange(null)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.preview {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 100%;
|
||||
transition: border-color 130ms ease-in-out;
|
||||
box-shadow: 0 0 0 1px var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
.preview:hover {
|
||||
cursor: pointer;
|
||||
box-shadow: 0 0 2px 2px var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
.spectrum-Popover {
|
||||
width: 100%;
|
||||
z-index: 999;
|
||||
top: 100%;
|
||||
padding: var(--spacing-l) var(--spacing-xl);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-xl);
|
||||
}
|
||||
.colors {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
.heading {
|
||||
font-size: var(--font-size-s);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.14px;
|
||||
flex: 1 1 auto;
|
||||
text-transform: uppercase;
|
||||
grid-column: 1 / 5;
|
||||
margin-bottom: var(--spacing-s);
|
||||
}
|
||||
.color {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 0 0 1px var(--spectrum-global-color-gray-300);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.color:hover {
|
||||
cursor: pointer;
|
||||
box-shadow: 0 0 2px 2px var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
.custom {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
gap: var(--spacing-m);
|
||||
margin-right: var(--spacing-xs);
|
||||
}
|
||||
.category--custom .heading {
|
||||
margin-bottom: var(--spacing-xs);
|
||||
}
|
||||
</style>
|
|
@ -10,6 +10,7 @@
|
|||
export let id = null
|
||||
export let readonly = false
|
||||
export let updateOnChange = true
|
||||
export let quiet = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let focus = false
|
||||
|
@ -59,6 +60,7 @@
|
|||
|
||||
<div
|
||||
class="spectrum-Textfield"
|
||||
class:spectrum-Textfield--quiet={quiet}
|
||||
class:is-invalid={!!error}
|
||||
class:is-disabled={disabled}
|
||||
class:is-focused={focus}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
export let readonly = false
|
||||
export let error = null
|
||||
export let updateOnChange = true
|
||||
export let quiet = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const onChange = e => {
|
||||
|
@ -29,6 +30,7 @@
|
|||
{value}
|
||||
{placeholder}
|
||||
{type}
|
||||
{quiet}
|
||||
on:change={onChange}
|
||||
on:click
|
||||
on:input
|
||||
|
|
|
@ -55,6 +55,7 @@ export { default as Search } from "./Form/Search.svelte"
|
|||
export { default as Pagination } from "./Pagination/Pagination.svelte"
|
||||
export { default as Badge } from "./Badge/Badge.svelte"
|
||||
export { default as StatusLight } from "./StatusLight/StatusLight.svelte"
|
||||
export { default as ColorPicker } from "./ColorPicker/ColorPicker.svelte"
|
||||
|
||||
// Typography
|
||||
export { default as Body } from "./Typography/Body.svelte"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Input, Select } from "@budibase/bbui"
|
||||
import { Input, Select, ColorPicker } from "@budibase/bbui"
|
||||
import FlatButtonGroup from "./PropertyControls/FlatButtonGroup"
|
||||
import Colorpicker from "./PropertyControls/ColorPicker.svelte"
|
||||
// import Colorpicker from "./PropertyControls/ColorPicker.svelte"
|
||||
|
||||
export const layout = [
|
||||
{
|
||||
|
@ -274,61 +274,6 @@ export const size = {
|
|||
],
|
||||
}
|
||||
|
||||
export const position = [
|
||||
{
|
||||
label: "Position",
|
||||
key: "position",
|
||||
control: Select,
|
||||
options: [
|
||||
{ label: "Static", value: "static" },
|
||||
{ label: "Relative", value: "relative" },
|
||||
{ label: "Fixed", value: "fixed" },
|
||||
{ label: "Absolute", value: "absolute" },
|
||||
{ label: "Sticky", value: "sticky" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Top",
|
||||
key: "top",
|
||||
control: Input,
|
||||
placeholder: "px",
|
||||
},
|
||||
{
|
||||
label: "Right",
|
||||
key: "right",
|
||||
control: Input,
|
||||
placeholder: "px",
|
||||
},
|
||||
{
|
||||
label: "Bottom",
|
||||
key: "bottom",
|
||||
control: Input,
|
||||
placeholder: "px",
|
||||
},
|
||||
{
|
||||
label: "Left",
|
||||
key: "left",
|
||||
control: Input,
|
||||
placeholder: "px",
|
||||
},
|
||||
{
|
||||
label: "Z-index",
|
||||
key: "z-index",
|
||||
control: Select,
|
||||
options: [
|
||||
{ label: "-9999", value: "-9999" },
|
||||
{ label: "-3", value: "-3" },
|
||||
{ label: "-2", value: "-2" },
|
||||
{ label: "-1", value: "-1" },
|
||||
{ label: "0", value: "0" },
|
||||
{ label: "1", value: "1" },
|
||||
{ label: "2", value: "2" },
|
||||
{ label: "3", value: "3" },
|
||||
{ label: "9999", value: "9999" },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export const typography = [
|
||||
{
|
||||
label: "Font",
|
||||
|
@ -401,7 +346,7 @@ export const typography = [
|
|||
{
|
||||
label: "Color",
|
||||
key: "color",
|
||||
control: Colorpicker,
|
||||
control: ColorPicker,
|
||||
},
|
||||
{
|
||||
label: "align",
|
||||
|
@ -445,14 +390,13 @@ export const background = {
|
|||
{
|
||||
label: "Color",
|
||||
key: "background",
|
||||
control: Colorpicker,
|
||||
control: ColorPicker,
|
||||
},
|
||||
{
|
||||
label: "Gradient",
|
||||
key: "background-image",
|
||||
control: Select,
|
||||
options: [
|
||||
{ label: "None", value: "none" },
|
||||
{
|
||||
label: "Warm Flame",
|
||||
value:
|
||||
|
@ -534,21 +478,17 @@ export const border = {
|
|||
{
|
||||
label: "Color",
|
||||
key: "border-color",
|
||||
control: Colorpicker,
|
||||
control: ColorPicker,
|
||||
},
|
||||
{
|
||||
label: "Radius",
|
||||
key: "border-radius",
|
||||
control: Select,
|
||||
options: [
|
||||
{ label: "None", value: "0" },
|
||||
{ label: "X Small", value: "0.125rem" },
|
||||
{ label: "Small", value: "0.25rem" },
|
||||
{ label: "Medium", value: "0.5rem" },
|
||||
{ label: "Large", value: "1rem" },
|
||||
{ label: "X Large", value: "2rem" },
|
||||
{ label: "XX Large", value: "4rem" },
|
||||
{ label: "Round", value: "5678px" },
|
||||
{ label: "Round", value: "100%" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -556,12 +496,9 @@ export const border = {
|
|||
key: "border-width",
|
||||
control: Select,
|
||||
options: [
|
||||
{ label: "None", value: "0" },
|
||||
{ label: "X Small", value: "0.5px" },
|
||||
{ label: "Small", value: "1px" },
|
||||
{ label: "Medium", value: "2px" },
|
||||
{ label: "Large", value: "4px" },
|
||||
{ label: "X large", value: "8px" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -569,8 +506,6 @@ export const border = {
|
|||
key: "box-shadow",
|
||||
control: Select,
|
||||
options: [
|
||||
{ label: "None", value: "none" },
|
||||
{ label: "X Small", value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
|
||||
{
|
||||
label: "Small",
|
||||
value:
|
||||
|
@ -584,12 +519,7 @@ export const border = {
|
|||
{
|
||||
label: "Large",
|
||||
value:
|
||||
"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
|
||||
},
|
||||
{
|
||||
label: "X Large",
|
||||
value:
|
||||
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
|
||||
"0 8px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue