155 lines
2.9 KiB
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>
|