Sink.svelte (1365B)
1 <script lang="ts"> 2 import { RANGE, type Input } from '$lib/types'; 3 import Control from '$lib/Control.svelte'; 4 export let channel: 'l' | 'c' | 'h'; 5 export let onSinkConnect: null | ((ch: 'l' | 'c' | 'h') => void); 6 export let setInput: (input: Input) => void; 7 export let connected: boolean; 8 export let input: Input; 9 10 let _onSinkConnect: null | (() => void) = null; 11 $: _onSinkConnect = onSinkConnect ? onSinkConnect.bind(null, channel) : null; 12 $: classes = ['connect', _onSinkConnect && 'hl', connected && 'connected'] 13 .filter(Boolean) 14 .join(' '); 15 16 const NAMES = { 17 l: 'lightness', 18 c: 'chroma', 19 h: 'hue' 20 }; 21 </script> 22 23 <div class="sink" data-sink-ch={channel}> 24 {#if onSinkConnect} 25 <div class={classes} on:mouseup={_onSinkConnect} /> 26 {/if} 27 <button class={Boolean(_onSinkConnect) ? 'hl' : ''}> 28 {NAMES[channel]} 29 <Control {input} controlRange={RANGE.signal} {setInput} /> 30 </button> 31 </div> 32 33 <style> 34 .hl { 35 background: lightgreen; 36 } 37 .hl.connected { 38 background: red; 39 } 40 .sink { 41 position: relative; 42 } 43 .connect { 44 position: absolute; 45 top: -5px; 46 left: -5px; 47 bottom: -5px; 48 right: -5px; 49 opacity: 0.5; 50 } 51 .connect:hover { 52 background: green; 53 } 54 .connect.connected:hover { 55 background: red; 56 } 57 button { 58 margin: 5px; 59 width: 150px; 60 height: 40px; 61 padding: 10px 15px; 62 font-size: 16px; 63 border-radius: 10%; 64 } 65 </style>