Authentication
Authenticationは、ユーザーがサービスを利用するために本人確認を行う一連の画面コンポーネントです。
authentication/signin is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Card from '$lib/components/ui/atoms/Card.svelte';
import Input from '$lib/components/ui/atoms/Input.svelte';
import Label from '$lib/components/ui/atoms/Label.svelte';
import Message from '$lib/components/ui/items/Message.svelte';
import { Eye, EyeOff } from '@lucide/svelte';
let uid = $props.id();
// パスワードリセット画面へのURL
let forgotPasswordUrl = '#';
// 新規登録画面へのURL
let signUpUrl = '#';
const formValues = $state({
email: '',
password: '',
});
let showPassword = $state(false);
let showMessage = $state(false);
let isSubmittable = $derived([formValues.email, formValues.password].every((value) => value !== ''));
/** パスワードの表示・非表示を切り替える */
function togglePasswordVisibility() {
showPassword = !showPassword;
}
/**
* ログイン情報を送信する
* @param event イベント
*/
function handleSubmit(event: Event) {
event.preventDefault();
showMessage = true;
}
</script>
<div class="flex flex-col justify-center size-full min-h-screen p-6 bg-subtle overflow-y-auto">
<h2 class="text-center font-semibold text-2xl/tight text-foreground mb-6">ログイン</h2>
<Card class="max-w-lg w-full p-14 bg-surface mx-auto mb-4 max-md:px-6 max-md:py-12 box-shadow:none">
<form onsubmit={handleSubmit}>
{#if showMessage}
<Message class="mb-6" variant="danger">
<p class="text-foreground text-sm/normal">メールアドレスまたはパスワードが誤っています。</p>
</Message>
{/if}
<div class="mb-6">
<Label class="mb-2 cursor-pointer" for="email-{uid}">メールアドレス</Label>
<Input id="email-{uid}" class="w-full" type="email" placeholder="email@example.com" required bind:value={formValues.email} />
</div>
<div class="mb-8">
<Label class="mb-2 cursor-pointer" for="password-{uid}">パスワード</Label>
<Input id="password-{uid}" class="w-full" type={showPassword ? 'text' : 'password'} placeholder="入力してください" required bind:value={formValues.password}>
{#snippet endContent()}
<button type="button" class="outline-offset-2 outline-ring cursor-pointer focus-visible:rounded-md focus-visible:outline-2" aria-label={showPassword ? 'パスワードを隠す' : 'パスワードを表示する'} onclick={togglePasswordVisibility}>
{#if showPassword}
<Eye class="text-muted-foreground" size="1rem" />
{:else}
<EyeOff class="text-muted-foreground" size="1rem" />
{/if}
</button>
{/snippet}
</Input>
</div>
<Button class="w-full" type="submit" size="small" disabled={!isSubmittable}>ログイン</Button>
</form>
</Card>
<div class="flex flex-col items-center w-fit gap-2 text-muted-foreground text-sm/normal mx-auto">
<a class="outline-offset-2 outline-ring transition-colors duration-200 ease-in-out underline underline-offset-4 decoration-transparent focus-visible:rounded-md hover:text-accent-foreground focus-visible:outline-2 hover:decoration-current" href={forgotPasswordUrl}>パスワードをお忘れの方はこちら</a>
<a class="outline-offset-2 outline-ring transition-colors duration-200 ease-in-out underline underline-offset-4 decoration-transparent focus-visible:rounded-md hover:text-accent-foreground focus-visible:outline-2 hover:decoration-current" href={signUpUrl}>アカウントを持っていない方はこちら</a>
</div>
</div>
依存コンポーネント
Authenticationを使うときは、以下のコンポーネントもダウンロードが必要です。
サンプル
Signup
サービスを初めて利用するユーザーが新規アカウントを作成する画面です。
authentication/signup is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Card from '$lib/components/ui/atoms/Card.svelte';
import Input from '$lib/components/ui/atoms/Input.svelte';
import Label from '$lib/components/ui/atoms/Label.svelte';
let uid = $props.id();
// ログイン画面へのURL
let loginUrl = '#';
const formValues = $state({
email: '',
});
let isSubmittable = $derived(formValues.email !== '');
/**
* ユーザー情報を送信する
* @param event イベント
*/
function handleSubmit(event: Event) {
event.preventDefault();
}
</script>
<div class="flex flex-col justify-center size-full min-h-screen p-6 bg-subtle overflow-y-auto">
<h2 class="text-center font-semibold text-2xl/tight text-foreground mb-6">アカウントの新規作成</h2>
<Card class="max-w-lg w-full p-14 bg-surface mx-auto mb-4 max-md:px-6 max-md:py-12 box-shadow:none">
<form class="flex flex-col gap-8" onsubmit={handleSubmit}>
<div>
<Label class="mb-2 cursor-pointer" for="email-{uid}">メールアドレス</Label>
<Input id="email-{uid}" class="w-full" type="email" placeholder="email@example.com" required bind:value={formValues.email} />
</div>
<Button class="w-full" type="submit" size="small" disabled={!isSubmittable}>新規登録用メールを送信</Button>
</form>
</Card>
<div class="flex flex-col items-center w-fit gap-2 text-muted-foreground text-sm/normal transition-colors mx-auto">
<a class="outline-offset-2 outline-ring transition-colors duration-200 ease-in-out underline underline-offset-4 decoration-transparent focus-visible:rounded-md hover:text-accent-foreground focus-visible:outline-2 hover:decoration-current" href={loginUrl}>すでにアカウントをお持ちの方はこちら</a>
</div>
</div>
Registration
サービスを初めて利用するユーザーが、新規アカウントの情報を入力して登録する画面です。
authentication/registration is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Card from '$lib/components/ui/atoms/Card.svelte';
import Checkbox from '$lib/components/ui/atoms/Checkbox.svelte';
import ImageUploader from '$lib/components/ui/atoms/ImageUploader.svelte';
import Input from '$lib/components/ui/atoms/Input.svelte';
import Label from '$lib/components/ui/atoms/Label.svelte';
import Message from '$lib/components/ui/items/Message.svelte';
import { Eye, EyeOff } from '@lucide/svelte';
let uid = $props.id();
// 利用規約のURL
let termsUrl = '#';
// プライバシーポリシーのURL
let privacyUrl = '#';
// ユーザー情報
const formValues = $state({
name: '',
email: 'rabeeui@example.com',
password: '',
confirmPassword: '',
iconSrc: null as string | null,
isAgreed: false,
});
let showPassword = $state(false);
let showConfirmPassword = $state(false);
let showMessage = $state(false);
let isSubmittable = $derived(
[formValues.name, formValues.email, formValues.password, formValues.confirmPassword].every((value) => value !== '') &&
formValues.password === formValues.confirmPassword &&
formValues.isAgreed,
);
/** パスワードの表示・非表示を切り替える */
function togglePasswordVisibility() {
showPassword = !showPassword;
}
/** 確認用パスワードの表示・非表示を切り替える */
function toggleConfirmPasswordVisibility() {
showConfirmPassword = !showConfirmPassword;
}
/**
* ユーザー情報を送信する
* @param event イベント
*/
function handleSubmit(event: Event) {
event.preventDefault();
showMessage = true;
}
</script>
<div class="flex flex-col justify-center size-full min-h-screen p-6 bg-subtle overflow-y-auto">
<h2 class="text-center font-semibold text-2xl/tight text-foreground mb-6">アカウント情報の登録</h2>
<Card class="max-w-lg w-full p-14 bg-surface mx-auto max-md:px-6 max-md:py-12 box-shadow:none">
<form onsubmit={handleSubmit}>
<div class="flex flex-col gap-6">
{#if showMessage}
<Message variant="danger">
<p class="text-foreground text-sm/normal">エラーが発生しました。入力内容をご確認ください。</p>
</Message>
{/if}
<div>
<Label class="mb-2 cursor-pointer" for="name-{uid}">名前</Label>
<Input id="name-{uid}" class="w-full" placeholder="入力してください" required bind:value={formValues.name} />
</div>
<div>
<Label class="mb-2 cursor-pointer" for="email-{uid}">メールアドレス</Label>
<Input id="email-{uid}" class="w-full" type="email" placeholder="rabeeui@example.com" required bind:value={formValues.email} />
</div>
<div>
<Label class="mb-2 cursor-pointer" for="password-{uid}">パスワード</Label>
<Input id="password-{uid}" class="w-full" type={showPassword ? 'text' : 'password'} placeholder="入力してください" required bind:value={formValues.password}>
{#snippet endContent()}
<button type="button" class="outline-offset-2 outline-ring cursor-pointer focus-visible:rounded-md focus-visible:outline-2" aria-label={showPassword ? 'パスワードを隠す' : 'パスワードを表示する'} onclick={togglePasswordVisibility}>
{#if showPassword}
<Eye class="text-muted-foreground" size="1rem" />
{:else}
<EyeOff class="text-muted-foreground" size="1rem" />
{/if}
</button>
{/snippet}
</Input>
</div>
<div>
<Label class="mb-2 cursor-pointer" for="confirm-password-{uid}">確認用パスワード</Label>
<Input id="confirm-password-{uid}" class="w-full" type={showConfirmPassword ? 'text' : 'password'} placeholder="入力してください" required bind:value={formValues.confirmPassword}>
{#snippet endContent()}
<button type="button" class="outline-offset-2 outline-ring cursor-pointer focus-visible:rounded-md focus-visible:outline-2" aria-label={showConfirmPassword ? 'パスワードを隠す' : 'パスワードを表示する'} onclick={toggleConfirmPasswordVisibility}>
{#if showConfirmPassword}
<Eye class="text-muted-foreground" size="1rem" />
{:else}
<EyeOff class="text-muted-foreground" size="1rem" />
{/if}
</button>
{/snippet}
</Input>
</div>
<div>
<p class="font-medium text-sm/tight mb-2">プロフィール写真(任意)</p>
<ImageUploader class="outline-offset-2 outline-ring focus-visible:outline-2" src={formValues.iconSrc} onChangeImage={(src) => (formValues.iconSrc = src)} />
</div>
<Label class="!flex items-center gap-2 font-normal cursor-pointer">
<Checkbox bind:checked={formValues.isAgreed} />
<span class="text-foreground text-sm/normal transition-colors duration-200 ease-in-out"><a class="outline-offset-2 outline-ring underline cursor-pointer focus-visible:rounded-md focus-visible:outline-2" href={termsUrl} rel="noopener noreferrer">利用規約</a>・<a class="outline-offset-2 outline-ring underline cursor-pointer focus-visible:rounded-md focus-visible:outline-2" href={privacyUrl} rel="noopener noreferrer">プライバシーポリシー</a>に同意する</span>
</Label>
<Button class="w-full" type="submit" size="small" disabled={!isSubmittable}>アカウントを作成</Button>
</div>
</form>
</Card>
</div>
Signin
サービスを使ったことのあるユーザーがサインインする画面です。
authentication/signin is coming soon.
<script lang="ts">
import Button from '$lib/components/ui/atoms/Button.svelte';
import Card from '$lib/components/ui/atoms/Card.svelte';
import Input from '$lib/components/ui/atoms/Input.svelte';
import Label from '$lib/components/ui/atoms/Label.svelte';
import Message from '$lib/components/ui/items/Message.svelte';
import { Eye, EyeOff } from '@lucide/svelte';
let uid = $props.id();
// パスワードリセット画面へのURL
let forgotPasswordUrl = '#';
// 新規登録画面へのURL
let signUpUrl = '#';
const formValues = $state({
email: '',
password: '',
});
let showPassword = $state(false);
let showMessage = $state(false);
let isSubmittable = $derived([formValues.email, formValues.password].every((value) => value !== ''));
/** パスワードの表示・非表示を切り替える */
function togglePasswordVisibility() {
showPassword = !showPassword;
}
/**
* ログイン情報を送信する
* @param event イベント
*/
function handleSubmit(event: Event) {
event.preventDefault();
showMessage = true;
}
</script>
<div class="flex flex-col justify-center size-full min-h-screen p-6 bg-subtle overflow-y-auto">
<h2 class="text-center font-semibold text-2xl/tight text-foreground mb-6">ログイン</h2>
<Card class="max-w-lg w-full p-14 bg-surface mx-auto mb-4 max-md:px-6 max-md:py-12 box-shadow:none">
<form onsubmit={handleSubmit}>
{#if showMessage}
<Message class="mb-6" variant="danger">
<p class="text-foreground text-sm/normal">メールアドレスまたはパスワードが誤っています。</p>
</Message>
{/if}
<div class="mb-6">
<Label class="mb-2 cursor-pointer" for="email-{uid}">メールアドレス</Label>
<Input id="email-{uid}" class="w-full" type="email" placeholder="email@example.com" required bind:value={formValues.email} />
</div>
<div class="mb-8">
<Label class="mb-2 cursor-pointer" for="password-{uid}">パスワード</Label>
<Input id="password-{uid}" class="w-full" type={showPassword ? 'text' : 'password'} placeholder="入力してください" required bind:value={formValues.password}>
{#snippet endContent()}
<button type="button" class="outline-offset-2 outline-ring cursor-pointer focus-visible:rounded-md focus-visible:outline-2" aria-label={showPassword ? 'パスワードを隠す' : 'パスワードを表示する'} onclick={togglePasswordVisibility}>
{#if showPassword}
<Eye class="text-muted-foreground" size="1rem" />
{:else}
<EyeOff class="text-muted-foreground" size="1rem" />
{/if}
</button>
{/snippet}
</Input>
</div>
<Button class="w-full" type="submit" size="small" disabled={!isSubmittable}>ログイン</Button>
</form>
</Card>
<div class="flex flex-col items-center w-fit gap-2 text-muted-foreground text-sm/normal mx-auto">
<a class="outline-offset-2 outline-ring transition-colors duration-200 ease-in-out underline underline-offset-4 decoration-transparent focus-visible:rounded-md hover:text-accent-foreground focus-visible:outline-2 hover:decoration-current" href={forgotPasswordUrl}>パスワードをお忘れの方はこちら</a>
<a class="outline-offset-2 outline-ring transition-colors duration-200 ease-in-out underline underline-offset-4 decoration-transparent focus-visible:rounded-md hover:text-accent-foreground focus-visible:outline-2 hover:decoration-current" href={signUpUrl}>アカウントを持っていない方はこちら</a>
</div>
</div>