Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aform] add login utility component #113

Merged
merged 9 commits into from
Apr 22, 2024
72 changes: 72 additions & 0 deletions aform/src/components/utilities/Login.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<template>
<div class="login-container">
<div>
<div class="account-container">
<div class="account-header">
<h1 id="account-title">{{ headerTitle }}</h1>
<p id="account-subtitle">{{ headerSubtitle }}</p>
</div>

<form @submit="onSubmit">
<div class="login-form-container">
<div class="login-form-email login-form-element">
<label id="login-email" for="email" class="login-label">Email</label>
<input
id="email"
class="login-field"
name="email"
placeholder="[email protected]"
type="email"
auto-capitalize="none"
auto-complete="email"
auto-correct="off"
:disabled="isLoading" />
</div>

<div class="login-form-password login-form-element">
<label id="login-password" for="password" class="login-label">Password</label>
<input id="password" class="login-field" name="password" type="password" :disabled="isLoading" />
</div>

<button class="btn" :disabled="isLoading">
<span v-if="isLoading" class="material-symbols-outlined loading-icon"> progress_activity </span>
<span id="login-form-button">Login</span>
</button>
</div>
</form>

<button class="btn">
<span id="forgot-password-button">Forgot password?</span>
</button>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

withDefaults(
defineProps<{
headerTitle?: string
headerSubtitle?: string
}>(),
{
headerTitle: 'Login',
headerSubtitle: 'Enter your email and password to login',
}
)

const isLoading = ref(false)

function onSubmit(event: Event) {
event.preventDefault()
isLoading.value = true

// TODO: handle submit logic
}
</script>

<style>
@import url('../../theme/login.css');
</style>
132 changes: 132 additions & 0 deletions aform/src/theme/login.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
@import url('https://fonts.googleapis.com/css2?family=Arimo:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap');
@import url('@stonecrop/themes/default/default.css');
@import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200');

:root {
/* BTNS */
--btn-color: white;
--btn-border: #cccccc;
--btn-hover: #f2f2f2;
--btn-label-color: black;
}

.login-container {
width: 100%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-family: var(--font-family);
}

.account-container {
width: 100%;
margin-left: auto;
margin-top: 0.5rem;
margin-right: auto;
display: flex;
flex-direction: column;
justify-content: center;
}

.account-header {
display: flex;
flex-direction: column;
text-align: center;
margin-top: 0.5rem;
}

#account-title {
font-size: 1.5rem;
line-height: 2rem;
font-weight: 600;
letter-spacing: -0.025em;
margin: 0;
}

#account-subtitle {
font-size: 0.875rem;
line-height: 1.25rem;
margin: 1rem;
}

.login-form-container {
display: grid;
gap: 0.5rem;
}

.login-form-email,
.login-form-password {
display: grid;
gap: 0.25rem;
}
.login-form-element {
margin: 0.5rem 0;
}
.login-field {
padding: 0.5rem 0.25rem 0.25rem 0.5rem;
outline: 1px solid transparent;
border: 1px solid var(--input-border-color);
border-radius: 0.25rem;

&:focus {
border: 1px solid black;
}
}
.login-label {
position: absolute;
padding: 0;
background: white;
white-space: nowrap;
border-width: 0;
font-size: 0.7rem;
margin-left: 0.5rem;
margin-top: -0.7rem;
padding: 0.3rem;
}

#login-form-button {
margin-right: 0.5rem;
height: 1rem;
width: 1rem;
}
.btn {
background-color: var(--btn-color);
color: var(--btn-label-color);
border: 1px solid var(--btn-border);
margin: 0.5rem 0;
padding: 0.25rem;
position: relative;

&:hover {
background-color: var(--btn-hover);
}
&:disabled {
background-color: light-dark(rgba(239, 239, 239, 0.3), rgba(59, 59, 59, 0.3));
color: light-dark(rgb(84, 84, 84), rgb(170, 170, 170));
}
}
.disabled {
opacity: 0.5;
}
.loading-icon {
animation: spin 1s linear infinite forwards;
display: inline-block;
margin-right: 0.2rem;
line-height: 0;
font-size: 1rem;
position: relative;
top: 0.2rem;
}

/* ANIMATION */
@keyframes spin {
from {
transform: rotate(0deg);
}

to {
transform: rotate(360deg);
}
}
9 changes: 9 additions & 0 deletions aform/stories/login.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<Story title="login">
<Login />
</Story>
</template>

<script setup lang="ts">
import Login from '@/components/utilities/Login.vue'
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@stonecrop/aform",
"comment": "Add Login utility component",
"type": "none"
}
],
"packageName": "@stonecrop/aform"
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{ "path": "./atable" },
{ "path": "./desktop" },
{ "path": "./examples" },
{ "path": "./graphql-client" },
{ "path": "./graphql_client" },
{ "path": "./stonecrop" },
{ "path": "./utilities" }
]
Expand Down
Loading