Login Form
A common authentication pattern combining a card layout, input fields, and validation states.
Demo
Implementation
vue
<script setup lang="ts">
import { ref } from 'vue';
// 1. Component Imports (Default)
import CLCard from '@codeandfunction/callaloo/CLCard';
import CLInput from '@codeandfunction/callaloo/CLInput';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import CLLink from '@codeandfunction/callaloo/CLLink';
import CLThemeProvider from '@codeandfunction/callaloo/CLThemeProvider';
// 2. Enum & Type Imports (Named)
import {
CLButtonTypes,
CLColors,
CLColorVariants
CLHeadingLevels,
CLHeadingTypes,
CLIconNames,
CLInputTypes,
CLTextTypes,
} from '@codeandfunction/callaloo';
// 3. State & Logic
const email = ref('');
const password = ref('');
const isLoading = ref(false);
const handleLogin = async (): Promise<void> => {
isLoading.value = true;
await new Promise(resolve => setTimeout(resolve, 1500));
isLoading.value = false;
};
</script>
<template>
<div class="pattern-preview">
<CLThemeProvider>
<CLCard :border-radius="CLBorderRadius.Small" :variant="CLColorVariants.Outline" elevated>
<template #heading>
<div class="header-content">
<CLHeading :level="CLHeadingLevels.H2" :type="CLHeadingTypes.Large">Welcome Back</CLHeading>
<CLText :color="CLColors.Neutral" :type="CLTextTypes.Small">Please sign in to your account</CLText>
</div>
</template>
<form @submit.prevent="handleLogin" class="form-content">
<CLInput
id="email"
name="email"
label="Email"
v-model="email"
:prefix="CLIconNames.Mail"
:type="CLInputTypes.Email"
fluid
required
/>
<CLInput
id="password"
name="password"
label="Password"
v-model="password"
:prefix="CLIconNames.Lock"
:type="CLInputTypes.Password"
fluid
required
/>
<CLButton
:type="CLButtonTypes.Submit"
:color="CLColors.Primary"
:busy="isLoading"
:disabled="isLoading"
width="100%"
>
Sign In
</CLButton>
</form>
<template #footer>
<div class="footer-content">
<CLText :type="CLTextTypes.Small">
<CLLink href="#">Forgot Password?</CLLink>
</CLText>
</div>
</template>
</CLCard>
</CLThemeProvider>
</div>
</template>
<style scoped>
.pattern-preview {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 100%;
}
.header-content {
text-align: center;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-content {
display: flex;
flex-direction: column;
gap: 1.5rem;
padding: 1rem 0;
}
.footer-content {
display: flex;
justify-content: center;
}
</style>