<script lang="ts">
import { onMount, createEventDispatcher } from 'svelte';
export let keys: Set<string> = new Set();
let keysDeref = new Set(keys);
// $: keysDeref = new Set(keys);
let recording = false;
let dialog: HTMLDialogElement;
let dispatch = createEventDispatcher();
function onKeydown(event: KeyboardEvent) {
if (!recording) return;
if(event.key === 'Escape') {
recording = false;
return;
}
keysDeref.add(event.key.toLowerCase());
keysDeref = keysDeref;
}
function toggleRecording() {
recording = !recording;
if(recording) {
keysDeref.clear();
keysDeref = keysDeref;
}
}
function confirm() {
dispatch('close', keysDeref);
}
function cancel() {
dispatch('close', new Set());
}
onMount(() => {
dialog.showModal();
dialog.addEventListener('close', () => {
dispatch('close', new Set());
});
})
</script>
<svelte:window on:keydown={onKeydown} />
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<dialog bind:this={dialog} on:mousedown|stopPropagation>
<h2>Create Hotkey</h2>
<button on:click={toggleRecording} on:keydown|preventDefault class="recordBtn">
{#if recording}
Stop recording
{:else if keysDeref.size === 0}
Start recording
{:else}
Re-record
{/if}
</button>
<div class="hotkeyDisplay">
{#if keysDeref.size === 0}
{#if recording}
Press any keys
{:else}
No hotkey set
{/if}
{:else}
{Array.from(keysDeref).map(key => key === ' ' ? 'Space' : key).join(' + ')}
{/if}
</div>
<div class="completeContainer">
<button disabled={keysDeref.size === 0} class="confirm"
on:click={confirm}>
Confirm
</button>
<button class="cancel" on:click={cancel}>
No hotkey
</button>
</div>
</dialog>
<style>
dialog {
width: 400px;
height: 300px;
border-radius: 15px;
background-color: white;
border: 3px solid black;
display: flex;
flex-direction: column;
}
h2 {
width: 100%;
text-align: center;
}
button[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
.recordBtn {
width: 100%;
height: 50px;
border: none;
background-color: #f0f0f0;
cursor: pointer;
border-radius: 10px;
}
.hotkeyDisplay {
width: 100%;
text-align: center;
height: 80px;
overflow-y: auto;
margin-top: 20px;
}
.completeContainer {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.confirm, .cancel {
width: 40%;
border: none;
border-radius: 3px;
}
.confirm {
background-color: lightgreen;
}
.cancel {
background-color: lightcoral;
}
</style>