cryptgeon/frontend/src/lib/ui/TextInput.svelte

117 lines
2.3 KiB
Svelte
Raw Normal View History

2021-05-02 03:08:30 +02:00
<script lang="ts">
import { getRandomBytes, Hex } from '$lib/crypto'
2022-03-01 01:16:31 +01:00
import { fade } from 'svelte/transition'
import { t } from 'svelte-intl-precompile'
2021-05-02 03:08:30 +02:00
import copyToClipboard from 'copy-to-clipboard'
import Icon from './Icon.svelte'
export let label: string = ''
2022-03-01 02:00:01 +01:00
export let value: any
2021-05-02 03:08:30 +02:00
export let copy: boolean = false
export let random: boolean = false
const initialType = $$restProps.type
const isPassword = initialType === 'password'
let hidden = true
2022-03-01 01:16:31 +01:00
let notification: string | null = null
let notificationTimeout: NodeJS.Timeout | null = null
2021-05-02 03:08:30 +02:00
$: if (isPassword) {
value
$$restProps.type = hidden ? initialType : 'text'
}
function toggle() {
hidden = !hidden
}
function copyFN() {
2022-03-01 01:52:09 +01:00
copyToClipboard(value.toString())
2022-03-01 01:16:31 +01:00
notify($t('home.copied_to_clipboard'))
2021-05-02 03:08:30 +02:00
}
function randomFN() {
value = Hex.encode(getRandomBytes(20))
}
2022-03-01 01:16:31 +01:00
function notify(msg: string, delay: number = 2000) {
if (notificationTimeout) {
clearTimeout(notificationTimeout)
}
notificationTimeout = setTimeout(() => {
notification = null
}, delay)
notification = msg
}
2021-05-02 03:08:30 +02:00
</script>
<label>
2021-05-02 15:44:46 +02:00
<small disabled={$$restProps.disabled}>
2021-05-02 03:08:30 +02:00
{label}
</small>
<input bind:value {...$$restProps} />
<div class="icons">
{#if isPassword}
2022-03-01 01:52:09 +01:00
<Icon class="icon" icon={hidden ? 'eye' : 'eye-off'} on:click={toggle} />
2021-05-02 03:08:30 +02:00
{/if}
{#if random}
2022-03-01 01:52:09 +01:00
<Icon class="icon" icon="dice" on:click={randomFN} />
2021-05-02 03:08:30 +02:00
{/if}
{#if copy}
2022-03-01 01:52:09 +01:00
<Icon class="icon" icon="copy" on:click={copyFN} />
2021-05-02 03:08:30 +02:00
{/if}
</div>
2022-03-01 01:16:31 +01:00
{#if notification}
<div class="notification" transition:fade><small>{notification}</small></div>
{/if}
2021-05-02 03:08:30 +02:00
</label>
<style>
label {
position: relative;
display: block;
}
input {
width: 100%;
margin: 0;
border: 2px solid var(--ui-bg-1);
outline: none;
padding: 0.5rem;
height: 2.5rem;
}
input:hover,
input:focus {
border-color: var(--ui-clr-primary);
}
.icons {
border: 1px red;
position: absolute;
right: 0.3rem;
bottom: 0.3rem;
display: flex;
color: var(--ui-clr-primary);
}
.icons > :global(.icon) {
width: 1.5rem;
height: 1.5rem;
background-color: var(--ui-bg-1);
border: 2px solid var(--ui-bg-2);
padding: 1px;
cursor: pointer;
margin-left: 0.25rem;
}
.icons > :global(.icon:hover) {
border-color: var(--ui-clr-primary);
}
2022-03-01 01:16:31 +01:00
.notification {
text-align: right;
position: absolute;
right: 0;
bottom: -1.5em;
}
2021-05-02 03:08:30 +02:00
</style>