lint ✨
This commit is contained in:
parent
cada9bdb85
commit
2ac15c6b89
|
@ -1,5 +1,5 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { cloneDeep } from "lodash/fp";
|
import { cloneDeep } from "lodash/fp"
|
||||||
import api from "../api"
|
import api from "../api"
|
||||||
|
|
||||||
export const getBackendUiStore = () => {
|
export const getBackendUiStore = () => {
|
||||||
|
@ -12,8 +12,8 @@ export const getBackendUiStore = () => {
|
||||||
draftModel: {},
|
draftModel: {},
|
||||||
tabs: {
|
tabs: {
|
||||||
SETUP_PANEL: "SETUP",
|
SETUP_PANEL: "SETUP",
|
||||||
NAVIGATION_PANEL: "NAVIGATE"
|
NAVIGATION_PANEL: "NAVIGATE",
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = writable(INITIAL_BACKEND_UI_STATE)
|
const store = writable(INITIAL_BACKEND_UI_STATE)
|
||||||
|
@ -28,7 +28,7 @@ export const getBackendUiStore = () => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.selectedDatabase = db
|
state.selectedDatabase = db
|
||||||
if (models && models.length > 0) {
|
if (models && models.length > 0) {
|
||||||
store.actions.models.select(models[0]);
|
store.actions.models.select(models[0])
|
||||||
}
|
}
|
||||||
state.models = models
|
state.models = models
|
||||||
state.views = views
|
state.views = views
|
||||||
|
@ -49,24 +49,25 @@ export const getBackendUiStore = () => {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
models: {
|
models: {
|
||||||
select: model => store.update(state => {
|
select: model =>
|
||||||
state.selectedModel = model;
|
store.update(state => {
|
||||||
state.draftModel = cloneDeep(model);
|
state.selectedModel = model
|
||||||
state.selectedField = ""
|
state.draftModel = cloneDeep(model)
|
||||||
state.selectedView = `all_${model._id}`
|
state.selectedField = ""
|
||||||
state.tabs.SETUP_PANEL = "SETUP"
|
state.selectedView = `all_${model._id}`
|
||||||
return state;
|
state.tabs.SETUP_PANEL = "SETUP"
|
||||||
}),
|
return state
|
||||||
|
}),
|
||||||
save: async ({ instanceId, model }) => {
|
save: async ({ instanceId, model }) => {
|
||||||
const updatedModel = cloneDeep(model);
|
const updatedModel = cloneDeep(model)
|
||||||
|
|
||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
for (let key in updatedModel.schema) {
|
for (let key in updatedModel.schema) {
|
||||||
const field = updatedModel.schema[key]
|
const field = updatedModel.schema[key]
|
||||||
if (field.name && field.name !== key) {
|
if (field.name && field.name !== key) {
|
||||||
updatedModel.schema[field.name] = field
|
updatedModel.schema[field.name] = field
|
||||||
delete updatedModel.schema[key];
|
delete updatedModel.schema[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SAVE_MODEL_URL = `/api/${instanceId}/models`
|
const SAVE_MODEL_URL = `/api/${instanceId}/models`
|
||||||
|
@ -78,8 +79,10 @@ export const getBackendUiStore = () => {
|
||||||
if (!model._id) {
|
if (!model._id) {
|
||||||
state.models = [...state.models, savedModel]
|
state.models = [...state.models, savedModel]
|
||||||
} else {
|
} else {
|
||||||
const existingIdx = state.models.findIndex(({ _id }) => _id === model._id);
|
const existingIdx = state.models.findIndex(
|
||||||
state.models.splice(existingIdx, 1, savedModel);
|
({ _id }) => _id === model._id
|
||||||
|
)
|
||||||
|
state.models.splice(existingIdx, 1, savedModel)
|
||||||
state.models = state.models
|
state.models = state.models
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +98,7 @@ export const getBackendUiStore = () => {
|
||||||
|
|
||||||
state.draftModel.schema = {
|
state.draftModel.schema = {
|
||||||
...state.draftModel.schema,
|
...state.draftModel.schema,
|
||||||
[field.name]: field
|
[field.name]: field,
|
||||||
}
|
}
|
||||||
|
|
||||||
state.selectedField = field.name
|
state.selectedField = field.name
|
||||||
|
@ -103,7 +106,7 @@ export const getBackendUiStore = () => {
|
||||||
state.tabs.NAVIGATION_PANEL = "NAVIGATE"
|
state.tabs.NAVIGATION_PANEL = "NAVIGATE"
|
||||||
|
|
||||||
return state
|
return state
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
views: {
|
views: {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
i {
|
i {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -53,5 +53,4 @@
|
||||||
.tertiary {
|
.tertiary {
|
||||||
background: var(--white);
|
background: var(--white);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte"
|
||||||
import { backendUiStore } from "builderStore"
|
import { backendUiStore } from "builderStore"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
function linkRecord(record) {
|
function linkRecord(record) {
|
||||||
linkedRecords.push(record);
|
linkedRecords.push(record)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -65,4 +65,4 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { store, backendUiStore } from "builderStore"
|
import { store, backendUiStore } from "builderStore"
|
||||||
import { notifier } from "@beyonk/svelte-notifications";
|
import { notifier } from "@beyonk/svelte-notifications"
|
||||||
import { compose, map, get, flatten } from "lodash/fp"
|
import { compose, map, get, flatten } from "lodash/fp"
|
||||||
import ActionButton from "components/common/ActionButton.svelte"
|
import ActionButton from "components/common/ActionButton.svelte"
|
||||||
import LinkedRecordSelector from "components/common/LinkedRecordSelector.svelte"
|
import LinkedRecordSelector from "components/common/LinkedRecordSelector.svelte"
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
backendUiStore.update(state => {
|
backendUiStore.update(state => {
|
||||||
state.selectedView = state.selectedView
|
state.selectedView = state.selectedView
|
||||||
onClosed()
|
onClosed()
|
||||||
notifier.success("Record created successfully.");
|
notifier.success("Record created successfully.")
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
<form on:submit|preventDefault class="uk-form-stacked">
|
<form on:submit|preventDefault class="uk-form-stacked">
|
||||||
{#each modelSchema as [key, meta]}
|
{#each modelSchema as [key, meta]}
|
||||||
<div class="uk-margin">
|
<div class="uk-margin">
|
||||||
{#if meta.type === "link"}
|
{#if meta.type === 'link'}
|
||||||
<LinkedRecordSelector modelId={meta.modelId} />
|
<LinkedRecordSelector modelId={meta.modelId} />
|
||||||
{:else}
|
{:else}
|
||||||
<RecordFieldControl
|
<RecordFieldControl
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
import { store, backendUiStore } from "builderStore"
|
import { store, backendUiStore } from "builderStore"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import getIcon from "../common/icon"
|
import getIcon from "../common/icon"
|
||||||
import {
|
import { CreateEditViewModal } from "components/database/ModelDataTable/modals"
|
||||||
CreateEditViewModal,
|
|
||||||
} from "components/database/ModelDataTable/modals"
|
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
|
|
||||||
const { open, close } = getContext("simple-modal")
|
const { open, close } = getContext("simple-modal")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import * as blockDefinitions from "constants/backend"
|
import * as blockDefinitions from "constants/backend"
|
||||||
import { backendUiStore } from "builderStore";
|
import { backendUiStore } from "builderStore"
|
||||||
import Block from "components/common/Block.svelte"
|
import Block from "components/common/Block.svelte"
|
||||||
|
|
||||||
const HEADINGS = [
|
const HEADINGS = [
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { backendUiStore } from "builderStore";
|
import { backendUiStore } from "builderStore"
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from "svelte/transition"
|
||||||
import { FIELDS, BLOCKS, MODELS } from "constants/backend";
|
import { FIELDS, BLOCKS, MODELS } from "constants/backend"
|
||||||
import Block from "components/common/Block.svelte";
|
import Block from "components/common/Block.svelte"
|
||||||
|
|
||||||
function addNewField(field) {
|
function addNewField(field) {
|
||||||
backendUiStore.actions.models.addField(field);
|
backendUiStore.actions.models.addField(field)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -20,7 +20,11 @@
|
||||||
<p>Blocks are pre-made fields and help you build your model quicker.</p>
|
<p>Blocks are pre-made fields and help you build your model quicker.</p>
|
||||||
<div class="blocks">
|
<div class="blocks">
|
||||||
{#each Object.values(FIELDS) as field}
|
{#each Object.values(FIELDS) as field}
|
||||||
<Block primary title={field.name} icon={field.icon} on:click={() => addNewField(field)} />
|
<Block
|
||||||
|
primary
|
||||||
|
title={field.name}
|
||||||
|
icon={field.icon}
|
||||||
|
on:click={() => addNewField(field)} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,7 +34,11 @@
|
||||||
<p>Blocks are pre-made fields and help you build your model quicker.</p>
|
<p>Blocks are pre-made fields and help you build your model quicker.</p>
|
||||||
<div class="blocks">
|
<div class="blocks">
|
||||||
{#each Object.values(BLOCKS) as field}
|
{#each Object.values(BLOCKS) as field}
|
||||||
<Block secondary title={field.name} icon={field.icon} on:click={() => addNewField(field)} />
|
<Block
|
||||||
|
secondary
|
||||||
|
title={field.name}
|
||||||
|
icon={field.icon}
|
||||||
|
on:click={() => addNewField(field)} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -78,4 +86,4 @@
|
||||||
grid-auto-columns: 110px;
|
grid-auto-columns: 110px;
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from "svelte/transition"
|
||||||
import { Switcher } from "@budibase/bbui"
|
import { Switcher } from "@budibase/bbui"
|
||||||
import { goto } from "@sveltech/routify"
|
import { goto } from "@sveltech/routify"
|
||||||
import { store, backendUiStore } from "builderStore"
|
import { store, backendUiStore } from "builderStore"
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
$: selectedTab = $backendUiStore.tabs.NAVIGATION_PANEL
|
$: selectedTab = $backendUiStore.tabs.NAVIGATION_PANEL
|
||||||
|
|
||||||
function selectModel(model, fieldName) {
|
function selectModel(model, fieldName) {
|
||||||
backendUiStore.actions.models.select(model)
|
backendUiStore.actions.models.select(model)
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
backendUiStore.update(state => {
|
backendUiStore.update(state => {
|
||||||
state.selectedField = fieldName
|
state.selectedField = fieldName
|
||||||
return state
|
return state
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +47,14 @@
|
||||||
{#if $backendUiStore.selectedDatabase && $backendUiStore.selectedDatabase._id}
|
{#if $backendUiStore.selectedDatabase && $backendUiStore.selectedDatabase._id}
|
||||||
<div class="hierarchy">
|
<div class="hierarchy">
|
||||||
<div class="components-list-container">
|
<div class="components-list-container">
|
||||||
<Switcher headings={HEADINGS} bind:value={$backendUiStore.tabs.NAVIGATION_PANEL}>
|
<Switcher
|
||||||
|
headings={HEADINGS}
|
||||||
|
bind:value={$backendUiStore.tabs.NAVIGATION_PANEL}>
|
||||||
{#if selectedTab === 'NAVIGATE'}
|
{#if selectedTab === 'NAVIGATE'}
|
||||||
<Button secondary wide on:click={setupForNewModel}>Create New Model</Button>
|
<Button secondary wide on:click={setupForNewModel}>
|
||||||
<div class="hierarchy-items-container">
|
Create New Model
|
||||||
|
</Button>
|
||||||
|
<div class="hierarchy-items-container">
|
||||||
{#each $backendUiStore.models as model}
|
{#each $backendUiStore.models as model}
|
||||||
<ListItem
|
<ListItem
|
||||||
selected={!$backendUiStore.selectedField && model._id === $backendUiStore.selectedModel._id}
|
selected={!$backendUiStore.selectedField && model._id === $backendUiStore.selectedModel._id}
|
||||||
|
|
|
@ -38,44 +38,42 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Required</label>
|
<label>Required</label>
|
||||||
<input type="checkbox" />
|
<input type="checkbox" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if field.type === 'string'}
|
{#if field.type === 'string'}
|
||||||
<NumberBox
|
<NumberBox
|
||||||
label="Max Length"
|
label="Max Length"
|
||||||
bind:value={field.constraints.length.maximum} />
|
bind:value={field.constraints.length.maximum} />
|
||||||
<ValuesList
|
<ValuesList label="Categories" bind:values={field.constraints.inclusion} />
|
||||||
label="Categories"
|
{:else if field.type === 'datetime'}
|
||||||
bind:values={field.constraints.inclusion} />
|
<DatePicker
|
||||||
{:else if field.type === 'datetime'}
|
label="Min Value"
|
||||||
<DatePicker
|
bind:value={field.constraints.datetime.earliest} />
|
||||||
label="Min Value"
|
<DatePicker
|
||||||
bind:value={field.constraints.datetime.earliest} />
|
label="Max Value"
|
||||||
<DatePicker
|
bind:value={field.constraints.datetime.latest} />
|
||||||
label="Max Value"
|
{:else if field.type === 'number'}
|
||||||
bind:value={field.constraints.datetime.latest} />
|
<NumberBox
|
||||||
{:else if field.type === 'number'}
|
label="Min Value"
|
||||||
<NumberBox
|
bind:value={field.constraints.numericality.greaterThanOrEqualTo} />
|
||||||
label="Min Value"
|
<NumberBox
|
||||||
bind:value={field.constraints.numericality.greaterThanOrEqualTo} />
|
label="Max Value"
|
||||||
<NumberBox
|
bind:value={field.constraints.numericality.lessThanOrEqualTo} />
|
||||||
label="Max Value"
|
{:else if field.type === 'link'}
|
||||||
bind:value={field.constraints.numericality.lessThanOrEqualTo} />
|
<div class="field">
|
||||||
{:else if field.type === 'link'}
|
<label>Link</label>
|
||||||
<div class="field">
|
<select class="budibase__input" bind:value={field.modelId}>
|
||||||
<label>Link</label>
|
<option value={''} />
|
||||||
<select class="budibase__input" bind:value={field.modelId}>
|
{#each $backendUiStore.models as model}
|
||||||
<option value={''} />
|
<option value={model._id}>{model.name}</option>
|
||||||
{#each $backendUiStore.models as model}
|
{/each}
|
||||||
<option value={model._id}>{model.name}</option>
|
</select>
|
||||||
{/each}
|
</div>
|
||||||
</select>
|
{/if}
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
$: edited =
|
$: edited =
|
||||||
$backendUiStore.selectedField ||
|
$backendUiStore.selectedField ||
|
||||||
$backendUiStore.draftModel &&
|
($backendUiStore.draftModel &&
|
||||||
$backendUiStore.draftModel.name !== $backendUiStore.selectedModel.name
|
$backendUiStore.draftModel.name !== $backendUiStore.selectedModel.name)
|
||||||
|
|
||||||
async function deleteModel() {
|
async function deleteModel() {
|
||||||
const model = $backendUiStore.selectedModel
|
const model = $backendUiStore.selectedModel
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default as ModelSetupNav } from "./ModelSetupNav.svelte";
|
export { default as ModelSetupNav } from "./ModelSetupNav.svelte"
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
<script>
|
<script>
|
||||||
import FlatButton from "./FlatButton.svelte";
|
import FlatButton from "./FlatButton.svelte"
|
||||||
|
|
||||||
export let format = "hex";
|
export let format = "hex"
|
||||||
export let onclick = format => {};
|
export let onclick = format => {}
|
||||||
|
|
||||||
let colorFormats = ["hex", "rgb", "hsl"];
|
let colorFormats = ["hex", "rgb", "hsl"]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="flatbutton-group">
|
||||||
|
{#each colorFormats as text}
|
||||||
|
<FlatButton
|
||||||
|
selected={format === text}
|
||||||
|
{text}
|
||||||
|
on:click={() => onclick(text)} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.flatbutton-group {
|
.flatbutton-group {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -16,12 +25,3 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="flatbutton-group">
|
|
||||||
{#each colorFormats as text}
|
|
||||||
<FlatButton
|
|
||||||
selected={format === text}
|
|
||||||
{text}
|
|
||||||
on:click={() => onclick(text)} />
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,123 +1,79 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from "svelte";
|
import { onMount, createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getColorFormat,
|
getColorFormat,
|
||||||
convertToHSVA,
|
convertToHSVA,
|
||||||
convertHsvaToFormat
|
convertHsvaToFormat,
|
||||||
} from "./utils.js";
|
} from "./utils.js"
|
||||||
import Slider from "./Slider.svelte";
|
import Slider from "./Slider.svelte"
|
||||||
import Palette from "./Palette.svelte";
|
import Palette from "./Palette.svelte"
|
||||||
import ButtonGroup from "./ButtonGroup.svelte";
|
import ButtonGroup from "./ButtonGroup.svelte"
|
||||||
import Input from "./Input.svelte";
|
import Input from "./Input.svelte"
|
||||||
|
|
||||||
export let value = "#3ec1d3ff";
|
export let value = "#3ec1d3ff"
|
||||||
export let format = "hexa";
|
export let format = "hexa"
|
||||||
|
|
||||||
let h = null;
|
let h = null
|
||||||
let s = null;
|
let s = null
|
||||||
let v = null;
|
let v = null
|
||||||
let a = null;
|
let a = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (format) {
|
if (format) {
|
||||||
convertAndSetHSVA()
|
convertAndSetHSVA()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
function convertAndSetHSVA() {
|
function convertAndSetHSVA() {
|
||||||
let hsva = convertToHSVA(value, format);
|
let hsva = convertToHSVA(value, format)
|
||||||
setHSVA(hsva);
|
setHSVA(hsva)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setHSVA([hue, sat, val, alpha]) {
|
function setHSVA([hue, sat, val, alpha]) {
|
||||||
h = hue;
|
h = hue
|
||||||
s = sat;
|
s = sat
|
||||||
v = val;
|
v = val
|
||||||
a = alpha;
|
a = alpha
|
||||||
}
|
}
|
||||||
|
|
||||||
//fired by choosing a color from the palette
|
//fired by choosing a color from the palette
|
||||||
function setSaturationAndValue({ detail }) {
|
function setSaturationAndValue({ detail }) {
|
||||||
s = detail.s;
|
s = detail.s
|
||||||
v = detail.v;
|
v = detail.v
|
||||||
value = convertHsvaToFormat([h, s, v, a], format);
|
value = convertHsvaToFormat([h, s, v, a], format)
|
||||||
dispatch("change", value)
|
dispatch("change", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setHue(hue) {
|
function setHue(hue) {
|
||||||
h = hue;
|
h = hue
|
||||||
value = convertHsvaToFormat([h, s, v, a], format);
|
value = convertHsvaToFormat([h, s, v, a], format)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAlpha(alpha) {
|
function setAlpha(alpha) {
|
||||||
a = alpha === "1.00" ? "1" :alpha;
|
a = alpha === "1.00" ? "1" : alpha
|
||||||
value = convertHsvaToFormat([h, s, v, a], format);
|
value = convertHsvaToFormat([h, s, v, a], format)
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeFormatAndConvert(f) {
|
function changeFormatAndConvert(f) {
|
||||||
format = f;
|
format = f
|
||||||
console.log(f)
|
console.log(f)
|
||||||
value = convertHsvaToFormat([h, s, v, a], format);
|
value = convertHsvaToFormat([h, s, v, a], format)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleColorInput(text) {
|
function handleColorInput(text) {
|
||||||
let f = getColorFormat(text)
|
let f = getColorFormat(text)
|
||||||
if(f) {
|
if (f) {
|
||||||
format = f;
|
format = f
|
||||||
value = text
|
value = text
|
||||||
convertAndSetHSVA()
|
convertAndSetHSVA()
|
||||||
dispatch("change", value)
|
dispatch("change", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.colorpicker-container {
|
|
||||||
display: flex;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 400;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 300px;
|
|
||||||
width: 250px;
|
|
||||||
background: #ffffff;
|
|
||||||
border-radius: 2px;
|
|
||||||
box-shadow: 0 0.15em 1.5em 0 rgba(0,0,0,.1), 0 0 1em 0 rgba(0,0,0,.03);
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-panel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 8px;
|
|
||||||
background: white;
|
|
||||||
border: 1px solid #d2d2d2
|
|
||||||
}
|
|
||||||
|
|
||||||
.alpha-hue-panel {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 25px 1fr;
|
|
||||||
grid-gap: 15px;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-color {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 1px solid #dedada;
|
|
||||||
}
|
|
||||||
|
|
||||||
.format-input-panel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="colorpicker-container">
|
<div class="colorpicker-container">
|
||||||
|
|
||||||
<Palette on:change={setSaturationAndValue} {h} {s} {v} {a} />
|
<Palette on:change={setSaturationAndValue} {h} {s} {v} {a} />
|
||||||
|
@ -143,3 +99,47 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.colorpicker-container {
|
||||||
|
display: flex;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 400;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 300px;
|
||||||
|
width: 250px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 0.15em 1.5em 0 rgba(0, 0, 0, 0.1),
|
||||||
|
0 0 1em 0 rgba(0, 0, 0, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 8px;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #d2d2d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alpha-hue-panel {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25px 1fr;
|
||||||
|
grid-gap: 15px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-color {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #dedada;
|
||||||
|
}
|
||||||
|
|
||||||
|
.format-input-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,143 +1,170 @@
|
||||||
<script>
|
<script>
|
||||||
import Colorpicker from "./Colorpicker.svelte"
|
import Colorpicker from "./Colorpicker.svelte"
|
||||||
import {createEventDispatcher, afterUpdate, beforeUpdate} from "svelte"
|
import { createEventDispatcher, afterUpdate, beforeUpdate } from "svelte"
|
||||||
import {buildStyle} from "./helpers.js"
|
import { buildStyle } from "./helpers.js"
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from "svelte/transition"
|
||||||
import {getColorFormat} from "./utils.js"
|
import { getColorFormat } from "./utils.js"
|
||||||
|
|
||||||
export let value = "#3ec1d3ff"
|
export let value = "#3ec1d3ff"
|
||||||
export let open = false;
|
export let open = false
|
||||||
export let width = "25px"
|
export let width = "25px"
|
||||||
export let height = "25px"
|
export let height = "25px"
|
||||||
|
|
||||||
let format = "hexa";
|
let format = "hexa"
|
||||||
let dimensions = {top: 0, left: 0}
|
let dimensions = { top: 0, left: 0 }
|
||||||
let colorPreview = null
|
let colorPreview = null
|
||||||
|
|
||||||
let previewHeight = null
|
let previewHeight = null
|
||||||
let previewWidth = null
|
let previewWidth = null
|
||||||
let pickerWidth = 250
|
let pickerWidth = 250
|
||||||
let pickerHeight = 300
|
let pickerHeight = 300
|
||||||
|
|
||||||
let anchorEl = null
|
let anchorEl = null
|
||||||
let parentNodes = [];
|
let parentNodes = []
|
||||||
let errorMsg = null
|
let errorMsg = null
|
||||||
|
|
||||||
$: previewStyle = buildStyle({width, height, background: value})
|
$: previewStyle = buildStyle({ width, height, background: value })
|
||||||
$: errorPreviewStyle = buildStyle({width, height})
|
$: errorPreviewStyle = buildStyle({ width, height })
|
||||||
$: pickerStyle = buildStyle({top: `${dimensions.top}px`, left: `${dimensions.left}px`})
|
$: pickerStyle = buildStyle({
|
||||||
|
top: `${dimensions.top}px`,
|
||||||
|
left: `${dimensions.left}px`,
|
||||||
|
})
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
beforeUpdate(() => {
|
beforeUpdate(() => {
|
||||||
format = getColorFormat(value)
|
format = getColorFormat(value)
|
||||||
if(!format) {
|
if (!format) {
|
||||||
errorMsg = `Colorpicker - ${value} is an unknown color format. Please use a hex, rgb or hsl value`
|
errorMsg = `Colorpicker - ${value} is an unknown color format. Please use a hex, rgb or hsl value`
|
||||||
console.error(errorMsg)
|
console.error(errorMsg)
|
||||||
}else{
|
} else {
|
||||||
errorMsg = null
|
errorMsg = null
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
afterUpdate(() => {
|
|
||||||
if(colorPreview && colorPreview.offsetParent && !anchorEl) {
|
|
||||||
//Anchor relative to closest positioned ancestor element. If none, then anchor to body
|
|
||||||
anchorEl = colorPreview.offsetParent
|
|
||||||
let curEl = colorPreview
|
|
||||||
let els = []
|
|
||||||
//Travel up dom tree from preview element to find parent elements that scroll
|
|
||||||
while(!anchorEl.isSameNode(curEl)) {
|
|
||||||
curEl = curEl.parentNode
|
|
||||||
let elOverflow = window.getComputedStyle(curEl).getPropertyValue("overflow")
|
|
||||||
if(/scroll|auto/.test(elOverflow)) {
|
|
||||||
els.push(curEl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parentNodes = els
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
function openColorpicker(event) {
|
|
||||||
if(colorPreview) {
|
|
||||||
const {top: spaceAbove, width, bottom, right, left: spaceLeft} = colorPreview.getBoundingClientRect()
|
|
||||||
const {innerHeight, innerWidth} = window
|
|
||||||
|
|
||||||
const {offsetLeft, offsetTop} = colorPreview
|
|
||||||
//get the scrollTop value for all scrollable parent elements
|
|
||||||
let scrollTop = parentNodes.reduce((scrollAcc, el) => scrollAcc += el.scrollTop, 0);
|
|
||||||
|
|
||||||
const spaceBelow = (innerHeight - spaceAbove) - previewHeight
|
|
||||||
const top = spaceAbove > spaceBelow ? (offsetTop - pickerHeight) - scrollTop : (offsetTop + previewHeight) - scrollTop
|
|
||||||
|
|
||||||
//TOO: Testing and Scroll Awareness for x Scroll
|
|
||||||
const spaceRight = (innerWidth - spaceLeft) + previewWidth
|
|
||||||
const left = spaceRight > spaceLeft ? (offsetLeft + previewWidth) + pickerWidth : offsetLeft - pickerWidth
|
|
||||||
|
|
||||||
dimensions = {top, left}
|
|
||||||
|
|
||||||
open = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function onColorChange(color) {
|
afterUpdate(() => {
|
||||||
value = color.detail;
|
if (colorPreview && colorPreview.offsetParent && !anchorEl) {
|
||||||
dispatch("change", color.detail)
|
//Anchor relative to closest positioned ancestor element. If none, then anchor to body
|
||||||
|
anchorEl = colorPreview.offsetParent
|
||||||
|
let curEl = colorPreview
|
||||||
|
let els = []
|
||||||
|
//Travel up dom tree from preview element to find parent elements that scroll
|
||||||
|
while (!anchorEl.isSameNode(curEl)) {
|
||||||
|
curEl = curEl.parentNode
|
||||||
|
let elOverflow = window
|
||||||
|
.getComputedStyle(curEl)
|
||||||
|
.getPropertyValue("overflow")
|
||||||
|
if (/scroll|auto/.test(elOverflow)) {
|
||||||
|
els.push(curEl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parentNodes = els
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function openColorpicker(event) {
|
||||||
|
if (colorPreview) {
|
||||||
|
const {
|
||||||
|
top: spaceAbove,
|
||||||
|
width,
|
||||||
|
bottom,
|
||||||
|
right,
|
||||||
|
left: spaceLeft,
|
||||||
|
} = colorPreview.getBoundingClientRect()
|
||||||
|
const { innerHeight, innerWidth } = window
|
||||||
|
|
||||||
|
const { offsetLeft, offsetTop } = colorPreview
|
||||||
|
//get the scrollTop value for all scrollable parent elements
|
||||||
|
let scrollTop = parentNodes.reduce(
|
||||||
|
(scrollAcc, el) => (scrollAcc += el.scrollTop),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
const spaceBelow = innerHeight - spaceAbove - previewHeight
|
||||||
|
const top =
|
||||||
|
spaceAbove > spaceBelow
|
||||||
|
? offsetTop - pickerHeight - scrollTop
|
||||||
|
: offsetTop + previewHeight - scrollTop
|
||||||
|
|
||||||
|
//TOO: Testing and Scroll Awareness for x Scroll
|
||||||
|
const spaceRight = innerWidth - spaceLeft + previewWidth
|
||||||
|
const left =
|
||||||
|
spaceRight > spaceLeft
|
||||||
|
? offsetLeft + previewWidth + pickerWidth
|
||||||
|
: offsetLeft - pickerWidth
|
||||||
|
|
||||||
|
dimensions = { top, left }
|
||||||
|
|
||||||
|
open = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onColorChange(color) {
|
||||||
|
value = color.detail
|
||||||
|
dispatch("change", color.detail)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="color-preview-container">
|
<div class="color-preview-container">
|
||||||
{#if !errorMsg}
|
{#if !errorMsg}
|
||||||
<div bind:this={colorPreview} bind:clientHeight={previewHeight} bind:clientWidth={previewWidth} class="color-preview" style={previewStyle} on:click={openColorpicker}></div>
|
<div
|
||||||
{#if open}
|
bind:this={colorPreview}
|
||||||
<div class="picker-container" bind:clientHeight={pickerHeight} bind:clientWidth={pickerWidth} style={pickerStyle}>
|
bind:clientHeight={previewHeight}
|
||||||
<Colorpicker on:change={onColorChange} {format} {value} />
|
bind:clientWidth={previewWidth}
|
||||||
</div>
|
class="color-preview"
|
||||||
<div on:click|self={() => open = false} class="overlay"></div>
|
style={previewStyle}
|
||||||
{/if}
|
on:click={openColorpicker} />
|
||||||
{:else}
|
{#if open}
|
||||||
<div class="color-preview preview-error" style={errorPreviewStyle}>
|
<div
|
||||||
<span>×</span>
|
class="picker-container"
|
||||||
</div>
|
bind:clientHeight={pickerHeight}
|
||||||
|
bind:clientWidth={pickerWidth}
|
||||||
|
style={pickerStyle}>
|
||||||
|
<Colorpicker on:change={onColorChange} {format} {value} />
|
||||||
|
</div>
|
||||||
|
<div on:click|self={() => (open = false)} class="overlay" />
|
||||||
{/if}
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<div class="color-preview preview-error" style={errorPreviewStyle}>
|
||||||
|
<span>×</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.color-preview-container{
|
.color-preview-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row nowrap;
|
flex-flow: row nowrap;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-preview {
|
.color-preview {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid #dedada;
|
border: 1px solid #dedada;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-error {
|
.preview-error {
|
||||||
background: #cccccc;
|
background: #cccccc;
|
||||||
color: #808080;
|
color: #808080;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.picker-container {
|
.picker-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay{
|
.overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
export let text = "";
|
export let text = ""
|
||||||
export let selected = false;
|
export let selected = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="flatbutton" class:selected on:click>{text}</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.flatbutton {
|
.flatbutton {
|
||||||
padding: 3px 15px;
|
padding: 3px 15px;
|
||||||
|
@ -22,5 +24,3 @@
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="flatbutton" class:selected on:click>{text}</div>
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
export let value = "";
|
export let value = ""
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input on:input type="text" {value} maxlength="25" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -22,7 +26,3 @@
|
||||||
border: 1px solid #dadada;
|
border: 1px solid #dadada;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div>
|
|
||||||
<input on:input type="text" {value} maxlength="25" />
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,41 +1,54 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from "svelte";
|
import { onMount, createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
export let h = 0;
|
export let h = 0
|
||||||
export let s = 0;
|
export let s = 0
|
||||||
export let v = 0;
|
export let v = 0
|
||||||
export let a = 1;
|
export let a = 1
|
||||||
|
|
||||||
let palette;
|
let palette
|
||||||
|
|
||||||
let paletteHeight, paletteWidth = 0;
|
|
||||||
|
|
||||||
|
let paletteHeight,
|
||||||
|
paletteWidth = 0
|
||||||
|
|
||||||
function handleClick(event) {
|
function handleClick(event) {
|
||||||
const { left, top } = palette.getBoundingClientRect();
|
const { left, top } = palette.getBoundingClientRect()
|
||||||
let clickX = (event.clientX - left)
|
let clickX = event.clientX - left
|
||||||
let clickY = (event.clientY - top)
|
let clickY = event.clientY - top
|
||||||
if((clickX > 0 && clickY > 0) && (clickX < paletteWidth && clickY < paletteHeight)) {
|
if (
|
||||||
|
clickX > 0 &&
|
||||||
|
clickY > 0 &&
|
||||||
|
clickX < paletteWidth && clickY < paletteHeight
|
||||||
|
) {
|
||||||
let s = (clickX / paletteWidth) * 100
|
let s = (clickX / paletteWidth) * 100
|
||||||
let v = 100 - ((clickY / paletteHeight) * 100)
|
let v = 100 - (clickY / paletteHeight) * 100
|
||||||
dispatch("change", {s, v})
|
dispatch("change", { s, v })
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$: pickerX = (s * paletteWidth) / 100;
|
$: pickerX = (s * paletteWidth) / 100
|
||||||
$: pickerY = paletteHeight * ((100 - v) / 100)
|
$: pickerY = paletteHeight * ((100 - v) / 100)
|
||||||
|
|
||||||
$: paletteGradient = `linear-gradient(to top, rgba(0, 0, 0, 1), transparent),
|
$: paletteGradient = `linear-gradient(to top, rgba(0, 0, 0, 1), transparent),
|
||||||
linear-gradient(to left, hsla(${h}, 100%, 50%, ${a}), rgba(255, 255, 255, ${a}))
|
linear-gradient(to left, hsla(${h}, 100%, 50%, ${a}), rgba(255, 255, 255, ${a}))
|
||||||
`;
|
`
|
||||||
$: style = `background: ${paletteGradient};`;
|
$: style = `background: ${paletteGradient};`
|
||||||
|
|
||||||
$: pickerStyle = `transform: translate(${pickerX - 8}px, ${pickerY - 8}px);`
|
$: pickerStyle = `transform: translate(${pickerX - 8}px, ${pickerY - 8}px);`
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={palette}
|
||||||
|
bind:clientHeight={paletteHeight}
|
||||||
|
bind:clientWidth={paletteWidth}
|
||||||
|
on:click={handleClick}
|
||||||
|
class="palette"
|
||||||
|
{style}>
|
||||||
|
<div class="picker" style={pickerStyle} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.palette {
|
.palette {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -54,7 +67,3 @@
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div bind:this={palette} bind:clientHeight={paletteHeight} bind:clientWidth={paletteWidth} on:click={handleClick} class="palette" {style}>
|
|
||||||
<div class="picker" style={pickerStyle} />
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,36 +1,47 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from "svelte";
|
import { onMount, createEventDispatcher } from "svelte"
|
||||||
import dragable from "./drag.js";
|
import dragable from "./drag.js"
|
||||||
|
|
||||||
export let value = 1;
|
export let value = 1
|
||||||
export let type = "hue";
|
export let type = "hue"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let slider;
|
let slider
|
||||||
let sliderWidth = 0;
|
let sliderWidth = 0
|
||||||
|
|
||||||
function handleClick(mouseX) {
|
function handleClick(mouseX) {
|
||||||
const { left, width } = slider.getBoundingClientRect();
|
const { left, width } = slider.getBoundingClientRect()
|
||||||
let clickPosition = mouseX - left;
|
let clickPosition = mouseX - left
|
||||||
|
|
||||||
let percentageClick = (clickPosition / sliderWidth).toFixed(2)
|
let percentageClick = (clickPosition / sliderWidth).toFixed(2)
|
||||||
|
|
||||||
if (percentageClick >= 0 && percentageClick <= 1) {
|
if (percentageClick >= 0 && percentageClick <= 1) {
|
||||||
let value =
|
let value = type === "hue" ? 360 * percentageClick : percentageClick
|
||||||
type === "hue"
|
dispatch("change", value)
|
||||||
? 360 * percentageClick
|
|
||||||
: percentageClick;
|
|
||||||
dispatch("change", value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: thumbPosition =
|
$: thumbPosition =
|
||||||
type === "hue" ? sliderWidth * (value / 360) : sliderWidth * value;
|
type === "hue" ? sliderWidth * (value / 360) : sliderWidth * value
|
||||||
|
|
||||||
$: style = `transform: translateX(${thumbPosition - 6}px);`;
|
$: style = `transform: translateX(${thumbPosition - 6}px);`
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={slider}
|
||||||
|
bind:clientWidth={sliderWidth}
|
||||||
|
on:click={event => handleClick(event.clientX)}
|
||||||
|
class="color-format-slider"
|
||||||
|
class:hue={type === 'hue'}
|
||||||
|
class:alpha={type === 'alpha'}>
|
||||||
|
<div
|
||||||
|
use:dragable
|
||||||
|
on:drag={e => handleClick(e.detail)}
|
||||||
|
class="slider-thumb"
|
||||||
|
{style} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.color-format-slider {
|
.color-format-slider {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -68,20 +79,6 @@
|
||||||
border: 1px solid #777676;
|
border: 1px solid #777676;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
cursor:grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div
|
|
||||||
bind:this={slider}
|
|
||||||
bind:clientWidth={sliderWidth}
|
|
||||||
on:click={event => handleClick(event.clientX)}
|
|
||||||
class="color-format-slider"
|
|
||||||
class:hue={type === 'hue'}
|
|
||||||
class:alpha={type === 'alpha'}>
|
|
||||||
<div
|
|
||||||
use:dragable
|
|
||||||
on:drag={e => handleClick(e.detail)}
|
|
||||||
class="slider-thumb"
|
|
||||||
{style} />
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -31,26 +31,26 @@
|
||||||
<FlatButtonGroup value={selectedCategory} {buttonProps} {onChange} />
|
<FlatButtonGroup value={selectedCategory} {buttonProps} {onChange} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="positioned-wrapper">
|
<div class="positioned-wrapper">
|
||||||
<div class="design-view-property-groups">
|
<div class="design-view-property-groups">
|
||||||
{#if propertyGroupNames.length > 0}
|
{#if propertyGroupNames.length > 0}
|
||||||
{#each propertyGroupNames as groupName}
|
{#each propertyGroupNames as groupName}
|
||||||
<PropertyGroup
|
<PropertyGroup
|
||||||
name={groupName}
|
name={groupName}
|
||||||
properties={getProperties(groupName)}
|
properties={getProperties(groupName)}
|
||||||
styleCategory={selectedCategory}
|
styleCategory={selectedCategory}
|
||||||
{onStyleChanged}
|
{onStyleChanged}
|
||||||
{componentDefinition}
|
{componentDefinition}
|
||||||
{componentInstance} />
|
{componentInstance} />
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="no-design">
|
<div class="no-design">
|
||||||
<span>This component does not have any design properties</span>
|
<span>This component does not have any design properties</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.design-view-container {
|
.design-view-container {
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
flex: 0 0 50px;
|
flex: 0 0 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.positioned-wrapper{
|
.positioned-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
if (v.target) {
|
if (v.target) {
|
||||||
let val = props.valueKey ? v.target[props.valueKey] : v.target.value
|
let val = props.valueKey ? v.target[props.valueKey] : v.target.value
|
||||||
onChange(key, val)
|
onChange(key, val)
|
||||||
}else if(v.detail) {
|
} else if (v.detail) {
|
||||||
onChange(key, v.detail)
|
onChange(key, v.detail)
|
||||||
} else {
|
} else {
|
||||||
onChange(key, v)
|
onChange(key, v)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
const FIELD_TYPES = ["string", "number", "boolean"]
|
|
||||||
|
|
||||||
export const FIELDS = {
|
export const FIELDS = {
|
||||||
PLAIN_TEXT: {
|
PLAIN_TEXT: {
|
||||||
name: "Plain Text",
|
name: "Plain Text",
|
||||||
|
@ -30,52 +28,52 @@ export const FIELDS = {
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// OPTIONS: {
|
OPTIONS: {
|
||||||
// name: "Options",
|
name: "Options",
|
||||||
// icon: "ri-list-check-2",
|
icon: "ri-list-check-2",
|
||||||
// type: "options",
|
type: "options",
|
||||||
// constraints: {
|
constraints: {
|
||||||
// type: "string",
|
type: "string",
|
||||||
// presence: false,
|
presence: false,
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// DATETIME: {
|
DATETIME: {
|
||||||
// name: "Date/Time",
|
name: "Date/Time",
|
||||||
// icon: "ri-calendar-event-fill",
|
icon: "ri-calendar-event-fill",
|
||||||
// type: "datetime",
|
type: "datetime",
|
||||||
// constraints: {
|
constraints: {
|
||||||
// type: "date",
|
type: "date",
|
||||||
// datetime: {},
|
datetime: {},
|
||||||
// presence: false,
|
presence: false,
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// IMAGE: {
|
IMAGE: {
|
||||||
// name: "File",
|
name: "File",
|
||||||
// icon: "ri-image-line",
|
icon: "ri-image-line",
|
||||||
// type: "file",
|
type: "file",
|
||||||
// constraints: {
|
constraints: {
|
||||||
// type: "string",
|
type: "string",
|
||||||
// presence: false,
|
presence: false,
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// FILE: {
|
FILE: {
|
||||||
// name: "Image",
|
name: "Image",
|
||||||
// icon: "ri-file-line",
|
icon: "ri-file-line",
|
||||||
// type: "file",
|
type: "file",
|
||||||
// constraints: {
|
constraints: {
|
||||||
// type: "string",
|
type: "string",
|
||||||
// presence: false,
|
presence: false,
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// DATA_LINK: {
|
DATA_LINK: {
|
||||||
// name: "Data Links",
|
name: "Data Links",
|
||||||
// icon: "ri-link",
|
icon: "ri-link",
|
||||||
// type: "link",
|
type: "link",
|
||||||
// modelId: null,
|
modelId: null,
|
||||||
// constraints: {
|
constraints: {
|
||||||
// type: "array",
|
type: "array",
|
||||||
// }
|
},
|
||||||
// },
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BLOCKS = {
|
export const BLOCKS = {
|
||||||
|
@ -115,11 +113,7 @@ export const BLOCKS = {
|
||||||
constraints: {
|
constraints: {
|
||||||
type: "string",
|
type: "string",
|
||||||
presence: false,
|
presence: false,
|
||||||
inclusion: [
|
inclusion: ["low", "medium", "high"],
|
||||||
"low",
|
|
||||||
"medium",
|
|
||||||
"high"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
END_DATE: {
|
END_DATE: {
|
||||||
|
@ -157,7 +151,7 @@ export const BLOCKS = {
|
||||||
modelId: null,
|
modelId: null,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: "array",
|
type: "array",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,15 +162,15 @@ export const MODELS = {
|
||||||
name: "Contacts",
|
name: "Contacts",
|
||||||
schema: {
|
schema: {
|
||||||
Name: BLOCKS.NAME,
|
Name: BLOCKS.NAME,
|
||||||
"Phone Number": BLOCKS.PHONE_NUMBER
|
"Phone Number": BLOCKS.PHONE_NUMBER,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
RECIPES: {
|
RECIPES: {
|
||||||
icon: "ri-link",
|
icon: "ri-link",
|
||||||
name: "Recipes",
|
name: "Recipes",
|
||||||
schema: {
|
schema: {
|
||||||
Name: BLOCKS.NAME,
|
Name: BLOCKS.NAME,
|
||||||
"Phone Number": BLOCKS.PHONE_NUMBER
|
"Phone Number": BLOCKS.PHONE_NUMBER,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { Button } from "@budibase/bbui";
|
import { Button } from "@budibase/bbui"
|
||||||
import EmptyModel from "components/nav/ModelNavigator/EmptyModel.svelte"
|
import EmptyModel from "components/nav/ModelNavigator/EmptyModel.svelte"
|
||||||
import ModelDataTable from "components/database/ModelDataTable"
|
import ModelDataTable from "components/database/ModelDataTable"
|
||||||
import { store, backendUiStore } from "builderStore"
|
import { store, backendUiStore } from "builderStore"
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
const { open, close } = getContext("simple-modal")
|
const { open, close } = getContext("simple-modal")
|
||||||
|
|
||||||
$: selectedModel = $backendUiStore.selectedModel
|
$: selectedModel = $backendUiStore.selectedModel
|
||||||
|
|
||||||
const createNewRecord = () => {
|
const createNewRecord = () => {
|
||||||
open(
|
open(
|
||||||
|
|
Loading…
Reference in New Issue