generateur_v3/frontend/src/components/forms/InputWithLabel.svelte

155 lines
2.9 KiB
Svelte

<script lang="ts">
import IoMdEye from 'svelte-icons/io/IoMdEye.svelte';
import IoMdEyeOff from 'svelte-icons/io/IoMdEyeOff.svelte';
export let type = 'text';
export let value: string | null = null;
export let label = '';
export let errors: string[] = [];
export let change: Function = (e: Event) => {};
function typeAction(node: HTMLInputElement) {
node.type = type;
}
let show = type != 'password';
const id = String(Math.random());
const toggle = () => {
const element = document.getElementById(id) as HTMLInputElement;
if (element === null) return;
element.type = show === true ? 'password' : 'text';
show = !show;
};
let test: HTMLInputElement;
export const focus = () => {
test.focus();
};
</script>
<span class="inputLabel" class:error={errors.length !== 0}>
<div style:position="relative">
<input
use:typeAction
on:input={(e)=>{change(e)}}
{id}
bind:value
{...$$restProps}
placeholder=""
bind:this={test}
/>
<!-- placeholder = "" pour que le label se place bien avec :placeholder-shown -->
<label for={id}>{label}</label>
{#if type == 'password'}
<div class="toggle" on:click={toggle} on:keypress={() => {}}>
{#if show == false}
<IoMdEyeOff />
{:else if show == true}
<IoMdEye />
{/if}
</div>
{/if}
</div>
<span class="bar" />
{#if errors.length !== 0}
<p class="error-msg">{errors[0]}</p>
{/if}
</span>
<style lang="scss">
@import '../../variables';
.error-msg {
color: $red;
font-weight: 800;
margin-top: 5px;
}
.toggle {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
right: 0;
width: 20px;
height: 20px;
cursor: pointer;
}
.inputLabel {
position: relative;
width: 100%;
display: flex;
flex-direction: column;
margin: 0;
margin-top: 10px;
}
input {
background-color: transparent;
border: none;
padding: 10px 10px 10px 5px;
border-bottom: 1px solid $input-border;
width: 100%;
font-size: 0.9em;
font-weight: 500;
color: #f8f8f8;
& ~ label {
font-size: 1em;
font-weight: normal;
position: absolute;
pointer-events: none;
left: 5px;
top: 10px;
transition: 0.3s ease all;
font-weight: 400;
color: #8e8e8e;
opacity: 0.4;
}
&:focus {
outline: none;
}
&:focus ~ label,
&:not(:placeholder-shown) ~ label {
top: -0.8em;
font-size: 12px;
color: $contrast;
opacity: 1;
font-weight: 600;
}
&:disabled ~ label {
color: grey;
}
&:focus ~ .bar:before {
width: 100%;
}
}
.error {
color: $red;
& input {
color: $red;
border-bottom: 1px solid $red;
&:focus ~ label,
&:not(:placeholder-shown):valid ~ label {
color: $red;
}
&:focus ~ .bar::before {
background-color: $red;
}
}
}
.bar {
position: relative;
display: block;
width: 100%;
&:before {
content: '';
height: 2px;
width: 0;
bottom: 0px;
position: absolute;
background: $contrast;
transition: 0.3s ease all;
left: 0%;
}
}
</style>