refactorings + basis of script editor.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
<script lang="ts" context="module">
|
||||
let nextId = 0;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { rgbString, type Color, stringifyColor, parseColor } from "$lib/models/color";
|
||||
import { hsToHsl, kToRgb, xyToRgb } from "$lib/utils/color";
|
||||
import ColorPicker, { selectedColorPicker } from "../ColorPicker.svelte";
|
||||
import BFormOption from "./BFormOption.svelte";
|
||||
import BFormParameter from "./BFormParameter.svelte";
|
||||
|
||||
export let value: string | null;
|
||||
|
||||
let colorPickerId = `BFormColorOption:${++nextId}`
|
||||
|
||||
let color: Color | null;
|
||||
$: color = parseColor(value);
|
||||
$: submit(color);
|
||||
|
||||
function toggle(event: MouseEvent & { currentTarget: EventTarget & HTMLDivElement; }) {
|
||||
if (event.shiftKey) {
|
||||
if (color !== null) {
|
||||
if ($selectedColorPicker !== colorPickerId) {
|
||||
$selectedColorPicker = colorPickerId;
|
||||
} else {
|
||||
$selectedColorPicker = null;
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (color === null || (color.hs == null && color.k == null)) {
|
||||
color = { k: 2750 }
|
||||
$selectedColorPicker = colorPickerId;
|
||||
} else {
|
||||
color = null;
|
||||
|
||||
if ($selectedColorPicker === colorPickerId) {
|
||||
$selectedColorPicker = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function submit(color: Color | null) {
|
||||
value = stringifyColor(color);
|
||||
}
|
||||
|
||||
let colorStr = "";
|
||||
$: {
|
||||
if (color !== null) {
|
||||
if (color.rgb != null) {
|
||||
colorStr = rgbString(color.rgb);
|
||||
} else if (color.hs != null) {
|
||||
colorStr = hsToHsl(color.hs);
|
||||
} else if (color.xy != null) {
|
||||
colorStr = rgbString(xyToRgb(color.xy));
|
||||
} else {
|
||||
colorStr = rgbString(kToRgb(color.k || 2750));
|
||||
}
|
||||
} else {
|
||||
colorStr = "#000000";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<BFormOption on:click={toggle} icon="palette" state={(color !== null) || null} color={colorStr}>
|
||||
{#if color != null}
|
||||
<div class="picker-wrapper">
|
||||
<ColorPicker bind:color={color} id={colorPickerId} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if color?.xy != null}
|
||||
<BFormParameter narrower label="X" type="number" max={1} step={0.01} bind:value={color.xy.x} />
|
||||
<BFormParameter narrower label="Y" type="number" max={1} step={0.01} bind:value={color.xy.y} />
|
||||
{/if}
|
||||
{#if color?.hs != null}
|
||||
<BFormParameter narrower label="Hue" type="number" max={360} step={1} bind:value={color.hs.hue} />
|
||||
<BFormParameter narrower label="Sat" type="number" max={1} step={0.01} bind:value={color.hs.sat} />
|
||||
{/if}
|
||||
{#if color?.rgb != null}
|
||||
<BFormParameter narrowest label="R" type="number" max={1} step={0.01} bind:value={color.rgb.red} />
|
||||
<BFormParameter narrowest label="G" type="number" max={1} step={0.01} bind:value={color.rgb.green} />
|
||||
<BFormParameter narrowest label="B" type="number" max={1} step={0.01} bind:value={color.rgb.blue} />
|
||||
{/if}
|
||||
{#if color?.k != null}
|
||||
<BFormParameter narrow label="Kelvin" type="number" min={1000} max={12000} step={50} bind:value={color.k} />
|
||||
{/if}
|
||||
</BFormOption>
|
||||
|
||||
<style lang="sass">
|
||||
div.picker-wrapper
|
||||
position: relative
|
||||
left: 0.5ch
|
||||
top: -11ch
|
||||
width: 0
|
||||
height: 0
|
||||
</style>
|
||||
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import BFormOption from "./BFormOption.svelte";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<BFormOption on:click={() => dispatch("delete")} red state icon=trash></BFormOption>
|
||||
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import BFormOption from "./BFormOption.svelte";
|
||||
import BFormParameter from "./BFormParameter.svelte";
|
||||
|
||||
export let value: number | null;
|
||||
|
||||
function update(percentage: number) {
|
||||
if (value !== null) {
|
||||
value = percentage / 100;
|
||||
}
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
if (value === null) {
|
||||
value = 0.50;
|
||||
} else {
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
|
||||
let percentage: number
|
||||
$: percentage = Math.max(Math.min((value || 0) * 100, 100), 0);
|
||||
$: update(percentage);
|
||||
</script>
|
||||
|
||||
<BFormOption on:click={toggle} icon="cirlce_notch" state={(value !== null) || null}>
|
||||
<BFormParameter type="number" label="%" bind:value={percentage} min={0} max={100} step={1} narrower />
|
||||
</BFormOption>
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="bform-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<style lang="sass">
|
||||
div.bform-body
|
||||
display: flex
|
||||
user-select: none
|
||||
font-size: 1rem
|
||||
width: 100%
|
||||
flex-wrap: wrap
|
||||
</style>
|
||||
@@ -0,0 +1,72 @@
|
||||
<script lang="ts" context="module">
|
||||
import { getContext, setContext } from "svelte";
|
||||
|
||||
export const ctxKey = {};
|
||||
|
||||
export function getBFormOptionEnabled() {
|
||||
return getContext(ctxKey) as Readable<boolean>
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import Icon, { type IconName } from "../Icon.svelte";
|
||||
import { writable, type Readable } from "svelte/store";
|
||||
|
||||
export let state: boolean | null = false;
|
||||
export let color: string = "hsl(240, 8%, 56%)";
|
||||
export let icon: IconName = "check";
|
||||
export let unclickable: boolean = false;
|
||||
export let red: boolean = false;
|
||||
|
||||
const enabled = writable(state === true);
|
||||
$: $enabled = state === true;
|
||||
|
||||
setContext(ctxKey, { subscribe: enabled.subscribe });
|
||||
</script>
|
||||
|
||||
<div class="bform-option" class:unclickable class:on={state === true} class:off={state === false} style="--color: {color}">
|
||||
<Icon on:click block name={icon} />
|
||||
<div class="bform-option-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="sass">
|
||||
@import "$lib/css/colors.sass"
|
||||
|
||||
div.bform-option
|
||||
box-shadow: 1px 1px 1px #000
|
||||
display: flex
|
||||
margin: 0.25em 0.25ch
|
||||
min-height: 1.9rem
|
||||
cursor: pointer
|
||||
background: $color-main1
|
||||
|
||||
:global(.icon)
|
||||
padding: 0.1em 0.5ch
|
||||
padding-top: 0.45em
|
||||
color: $color-main2
|
||||
|
||||
&.off
|
||||
background-color: $color-main2
|
||||
:global(.icon)
|
||||
color: $color-main4
|
||||
|
||||
&.on
|
||||
background-color: $color-main2
|
||||
:global(.icon)
|
||||
color: var(--color)
|
||||
|
||||
&.red
|
||||
background-color: $color-main2-red
|
||||
:global(.icon)
|
||||
color: $color-main6-redder
|
||||
|
||||
&.unclickable
|
||||
cursor: default
|
||||
|
||||
div.bform-option-body
|
||||
display: flex
|
||||
flex-direction: row
|
||||
cursor: default
|
||||
</style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<script lang="ts">
|
||||
import { getBFormOptionEnabled } from "./BFormOption.svelte";
|
||||
|
||||
export let label: string;
|
||||
export let type: "number" | "text" | "select";
|
||||
export let value: number | string;
|
||||
export let wide: boolean = false;
|
||||
export let narrow: boolean = false;
|
||||
export let narrower: boolean = false;
|
||||
export let narrowest: boolean = false;
|
||||
export let min: number = 0;
|
||||
export let max: number = 100;
|
||||
export let step: number = 1;
|
||||
export let options: {value: string | number, label: string}[] = [];
|
||||
|
||||
const enabled = getBFormOptionEnabled();
|
||||
</script>
|
||||
|
||||
{#if $enabled}
|
||||
<div class="bform-parameter" class:wide class:narrow class:narrower class:narrowest>
|
||||
<label for="input_{label}">{label}</label>
|
||||
{#if type === "number"}
|
||||
<input class="custom" on:blur on:focus type="number" bind:value={value} {min} {max} {step} />
|
||||
{:else if type === "text"}
|
||||
<input class="custom" on:blur on:focus type="text" bind:value={value} />
|
||||
{:else if type === "select"}
|
||||
<select class="custom" bind:value={value}>
|
||||
{#each options as opt (opt.value)}
|
||||
<option value={opt.value}>{opt.label}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="sass">
|
||||
@import "$lib/css/colors.sass"
|
||||
|
||||
div.bform-parameter
|
||||
display: flex
|
||||
flex-direction: column
|
||||
background: $color-main1
|
||||
height: 100%
|
||||
|
||||
> label
|
||||
font-size: 0.5em
|
||||
color: $color-main5
|
||||
text-align: center
|
||||
margin: 0
|
||||
line-height: 1em
|
||||
margin-top: 0.15rem !important
|
||||
padding-top: 0
|
||||
margin-bottom: -0em
|
||||
width: 10rem
|
||||
|
||||
> input, > select
|
||||
width: 10rem
|
||||
font-size: 0.9rem
|
||||
padding-left: 0
|
||||
background: none
|
||||
outline: none
|
||||
border: none
|
||||
text-align: center
|
||||
font-size: 1rem
|
||||
color: $color-main9
|
||||
|
||||
> option
|
||||
background: $color-main1
|
||||
|
||||
&::-webkit-inner-spin-button
|
||||
-webkit-appearance: none
|
||||
margin: 0
|
||||
|
||||
-webkit-appearance: none
|
||||
-moz-appearance: none
|
||||
moz-appearance: none
|
||||
appearance: none
|
||||
|
||||
&:focus
|
||||
color: $color-main13
|
||||
|
||||
> select
|
||||
margin-top: 0.08rem
|
||||
|
||||
&.wide
|
||||
> input, > label, > select
|
||||
text-align: left
|
||||
width: 20rem
|
||||
> label
|
||||
padding-left: 0.2rch
|
||||
|
||||
&.narrow
|
||||
> input, > label, > select
|
||||
width: calc(6rem + 0.22ch)
|
||||
|
||||
&.narrower
|
||||
> input, > label, > select
|
||||
width: 3rem
|
||||
|
||||
&.narrowest
|
||||
> input, > label, > select
|
||||
width: calc(2rem - 0.11ch)
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import BFormOption from "./BFormOption.svelte";
|
||||
|
||||
export let value: boolean | null;
|
||||
|
||||
function toggle() {
|
||||
if (value === null) {
|
||||
value = true;
|
||||
} else if (value === true) {
|
||||
value = false;
|
||||
} else {
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<BFormOption icon="power" on:click={toggle} state={value} color="#00FF00"></BFormOption>
|
||||
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import BFormOption from "./BFormOption.svelte";
|
||||
import BFormParameter from "./BFormParameter.svelte";
|
||||
|
||||
export let value: number | null;
|
||||
|
||||
function toggle() {
|
||||
if (value === null) {
|
||||
value = 20;
|
||||
} else {
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<BFormOption on:click={toggle} icon="temperature_half" state={(value !== null) || null}>
|
||||
{#if value != null}
|
||||
<BFormParameter type="number" label="Celsius" bind:value={value} min={10} max={32} step={1} narrower />
|
||||
{/if}
|
||||
</BFormOption>
|
||||
Reference in New Issue
Block a user