サインインブロック
SignInコンポーネントは、React、TypeScript、MUIで構築された完全にカスタマイズ可能でアクセシブルなサインインフォームです。モダンなデザインパターン、react-hook-formを使用したフォームバリデーション、柔軟なカスタマイズオプションを備えた完全な認証インターフェースを提供します。
🚀 インストール
npm install @nodeblocks/frontend-signin-block@0.3.0
📖 使用法
import {SignIn} from '@nodeblocks/frontend-signin-block';
- 基本的な使用法
- 高度な使用法
function BasicSignIn() { return ( <SignIn onChange={(setError, getValues, clearErrors) => { const values = getValues(); if (!values.email) { setError('email', {message: 'メールアドレスは必須です', type: 'required'}); } else { clearErrors('email'); } }} onSubmit={formData => { console.log('フォームが送信されました:', formData); }} > <SignIn.SignInTitle>おかえりなさい</SignIn.SignInTitle> <SignIn.EmailField label="メールアドレス" placeholder="メールアドレスを入力してください" /> <SignIn.PasswordField label="パスワード" placeholder="パスワードを入力してください" /> <SignIn.SignInButton>サインイン</SignIn.SignInButton> <SignIn.GotoSignUp> <a href="#signup">アカウントを作成</a> </SignIn.GotoSignUp> <SignIn.ResetPassword> <a href="#reset-password">パスワードをお忘れですか?</a> </SignIn.ResetPassword> </SignIn> ); }
function AdvancedSignIn() { return ( <SignIn onChange={(setError, getValues, clearErrors) => { const values = getValues(); if (!values.email) { setError('email', {message: 'メールアドレスが必要です', type: 'required'}); } else { clearErrors('email'); } if (!values.password) { setError('password', {message: 'パスワードが必要です', type: 'required'}); } else { clearErrors('password'); } }} onSubmit={formData => { console.log('ログイン:', formData); }} sx={{ maxWidth: '500px', margin: '0 auto', background: 'linear-gradient(145deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '20px', border: '1px solid #e2e8f0', }} > {({defaultBlocks, defaultBlockOrder}) => ({ blocks: { ...defaultBlocks, signInTitle: { ...defaultBlocks.signInTitle, props: { ...defaultBlocks.signInTitle.props, sx: { background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text', fontSize: '2rem', fontWeight: 'bold', textAlign: 'center', marginBottom: '8px', }, children: '企業ログイン', }, }, emailField: { ...defaultBlocks.emailField, props: { ...defaultBlocks.emailField.props, label: 'メールアドレス', placeholder: '例: user@company.com', sx: { '& .MuiOutlinedInput-root': { borderRadius: '10px', }, }, }, }, passwordField: { ...defaultBlocks.passwordField, props: { ...defaultBlocks.passwordField.props, label: 'パスワード', placeholder: 'パスワードを入力してください', sx: { '& .MuiOutlinedInput-root': { borderRadius: '10px', }, }, }, }, signInButton: { ...defaultBlocks.signInButton, props: { ...defaultBlocks.signInButton.props, sx: { background: '#3b82f6', borderRadius: '10px', py: 1.5, '&:hover': {background: '#2563eb'}, }, children: 'ログイン', }, }, gotoSignUp: { ...defaultBlocks.gotoSignUp, props: { ...defaultBlocks.gotoSignUp.props, sx: { textAlign: 'center', }, children: ( <span style={{color: '#64748b', fontSize: '14px'}}> アカウントをお持ちでない方は{' '} <a href="#signup" style={{color: '#3b82f6', textDecoration: 'none', fontWeight: '500'}}> 新規登録 </a> </span> ), }, }, resetPassword: { ...defaultBlocks.resetPassword, props: { ...defaultBlocks.resetPassword.props, sx: { textAlign: 'center', }, children: ( <a href="#reset-password" style={{color: '#64748b', fontSize: '14px', textDecoration: 'none'}}> パスワードをお忘れですか? </a> ), }, }, }, blockOrder: defaultBlockOrder, })} </SignIn> ); }
🔧 プロパティリファレンス
メインコンポーネントのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
onSubmit | SubmitHandler<T> | 必須 | 有効なデータでフォームが送信されたときにトリガーされるコールバック関数 |
onChange | (setError, getValues, clearErrors) => void | 必須 | フォーム値が変更されたときにトリガーされるコールバック関数。バリデーション用のフォーム制御関数を提供 |
defaultData | DefaultValues<T> | undefined | 初期レンダリング時にフィールドに設定するデフォルトフォーム値 |
data | T | undefined | 制御されたフォーム値 - 外部フォーム状態管理に使用 |
signupUrl | string | "/auth/signup" | GotoSignUpコンポーネントの登録リンクURL |
resetPasswordUrl | string | "/auth/resetpassword" | パスワードリセットリンクURL |
className | string | undefined | フォームコンテナスタイリング用の追加CSSクラス名 |
sx | SxProps | undefined | カスタムスタイリング用のMUI sxプロパティ |
children | BlocksOverride | undefined | デフォルトレンダリングをオーバーライドするカスタムブロックコンポーネント |
注意: このコンポーネントはMUI StackProps<'form'>(children、onChange、onSubmitを除く)を拡張します。component="form"を使用し、デフォルトspacing={4}、maxWidth: 496、px: 5、py: 6、borderRadius: 3です。
サブコンポーネント
SignInコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
SignIn.SignInTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Sign In" | タイトルコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
variant | string | "h4" | MUI Typographyバリアント |
component | string | "h1" | レンダリングするHTML要素 |
sx | SxProps | undefined | デフォルトtextAlign: 'center'を持つMUI sxプロパティ |
注意: このコンポーネントはMUI TypographyProps<'h1'> を拡張します。
SignIn.EmailField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "email" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Email" | 入力の上に表示されるフィールドラベル |
placeholder | string | "Please enter your email" | フィールドが空のときに表示されるプレースホルダーテキスト |
autoComplete | string | "username" | ブラウザオートコンプリートヒント |
required | boolean | true | フィールドが必須かどうか |
fullWidth | boolean | true | フィールドが全幅を占めるかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはMUI TextFieldProps を拡張します。エラー状態とヘルパーテキストはreact-hook-formによって自動管理されます。
SignIn.PasswordField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "password" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Password" | 入力の上に表示されるフィールドラベル |
placeholder | string | "Please enter your password" | フィールドが空のときに表示されるプレースホルダーテキスト |
autoComplete | string | "current-password" | ブラウザオートコンプリートヒント |
required | boolean | true | フィールドが必須かどうか |
fullWidth | boolean | true | フィールドが全幅を占めるかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはMUI TextFieldProps(typeを除く)を拡張します。Visibility/VisibilityOffアイコンによる組み込みパスワード表示切り替えを含みます。
SignIn.SignInButton
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Sign In" | ボタンテキストコンテンツ |
variant | string | "contained" | MUI Buttonバリアント |
size | string | "large" | MUI Buttonサイズ |
type | string | "submit" | HTMLボタンタイプ |
fullWidth | boolean | true | ボタンが全幅を占めるかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはMUI ButtonProps を拡張します。
SignIn.GotoSignUp
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
signupUrl | string | コンテキストから | 登録リンクURL |
children | ReactNode | /auth/signupへのリンク | 登録リンクセクションのコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
sx | SxProps | undefined | デフォルトtextAlign: 'center'とfontSize: body2を持つMUI sxプロパティ |
注意: このコンポーネントはMUI BoxProps を拡張します。
SignIn.ResetPassword
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
resetPasswordUrl | string | コンテキストから | パスワードリセットリンクURL |
children | ReactNode | /auth/resetpasswordへのリンク | パスワードリセットリンクセクションのコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
sx | SxProps | undefined | デフォルトtextAlign: 'center'とfontSize: body2を持つMUI sxプロパティ |
注意: このコンポーネントはMUI BoxProps を拡張します。
🎨 設定例
カスタムバリデーション
function ValidationSignIn() {
const handleSubmit = (formData: SignInFormData): void => {
console.log('バリデーション済みフォームが送信されました:', formData);
};
return (
<SignIn
onChange={(setError, getValues, clearErrors) => {
const {email, password} = getValues();
if (email && !email.includes('@')) {
setError('email', {message: '有効なメールアドレスを入力してください'});
} else {
clearErrors('email');
}
if (password && password.length < 8) {
setError('password', {message: 'パスワードは8文字以上である必要があります'});
} else {
clearErrors('password');
}
}}
onSubmit={handleSubmit}
>
<SignIn.SignInTitle
variant="h3"
sx={{
color: 'primary.main',
fontWeight: 'bold',
}}
>
おかえりなさい!
</SignIn.SignInTitle>
<SignIn.EmailField label="企業メール" placeholder="name@company.com" />
<SignIn.PasswordField label="アカウントパスワード" placeholder="安全なパスワードを入力してください" />
<SignIn.SignInButton>サインイン</SignIn.SignInButton>
<SignIn.GotoSignUp />
<SignIn.ResetPassword />
</SignIn>
);
}
ブロックオーバーライドパターン
function BlockOverrideSignIn() {
return (
<SignIn onSubmit={data => console.log(data)} onChange={() => {}}>
{({defaultBlocks}) => ({
blocks: {
...defaultBlocks,
// Add custom welcome message
welcomeMessage: (
<div
style={{
padding: '12px 16px',
backgroundColor: '#e3f2fd',
borderRadius: '8px',
textAlign: 'center',
color: '#1976d2',
}}
>
ダッシュボードにアクセスするにはサインインしてください
</div>
),
},
blockOrder: [
'signInTitle',
'welcomeMessage',
'emailField',
'passwordField',
'signInButton',
'gotoSignUp',
'resetPassword',
],
})}
</SignIn>
);
}
カスタムナビゲーションURL
<SignIn
signupUrl="/register"
resetPasswordUrl="/forgot-password"
onSubmit={handleSubmit}
onChange={handleChange}
/>
🔧 TypeScriptサポート
包括的な型定義による完全なTypeScriptサポート:
import {SignIn} from '@nodeblocks/frontend-signin-block';
import {
UseFormClearErrors,
UseFormGetValues,
UseFormSetError,
SubmitHandler,
} from 'react-hook-form';
// Default form data structure
type DefaultSignInFormData = {
email?: string;
password?: string;
};
// Extended form data type
type SignInFormData = DefaultSignInFormData & Record<string, unknown>;
// Custom form data with additional fields
interface CustomSignInFormData extends SignInFormData {
rememberMe?: boolean;
}
function TypedSignInExample() {
const handleSubmit: SubmitHandler<CustomSignInFormData> = formData => {
console.log('フォームが送信されました:', formData);
};
const handleChange = (
setError: UseFormSetError<CustomSignInFormData>,
getValues: UseFormGetValues<CustomSignInFormData>,
clearErrors: UseFormClearErrors<CustomSignInFormData>,
): void => {
const values = getValues();
// Custom validation
if (values.email && !values.email.includes('@')) {
setError('email', {message: 'Invalid email format'});
} else {
clearErrors('email');
}
};
return (
<SignIn<CustomSignInFormData>
onSubmit={handleSubmit}
onChange={handleChange}
defaultData={{email: 'user@example.com'}}
signupUrl="/register"
resetPasswordUrl="/forgot-password"
sx={{maxWidth: 480, mx: 'auto'}}
>
<SignIn.SignInTitle>おかえりなさい</SignIn.SignInTitle>
<SignIn.EmailField />
<SignIn.PasswordField />
<SignIn.SignInButton>ログイン</SignIn.SignInButton>
<SignIn.GotoSignUp>
<span>
アカウントをお持ちでない方は <a href="#register">サインアップ</a>
</span>
</SignIn.GotoSignUp>
<SignIn.ResetPassword>
<span>
<a href="#forgot-password">パスワードをお忘れですか?</a>
</span>
</SignIn.ResetPassword>
</SignIn>
);
}
📝 注意事項
- コンポーネントは
component="form"を持つMUIのStackコンポーネントをベースとして使用 - デフォルトスペーシングは
4、maxWidth: 496、px: 5、py: 6、borderRadius: 3 - フォーム状態は
mode: 'onBlur'でバリデーションを行うreact-hook-formで管理 onChangeコールバックはフォーム値が変更されたときにトリガー(useWatchを使用)- パスワードフィールドにはMUIの
Visibility/VisibilityOffアイコンによる組み込み表示切り替え - エラー状態とヘルパーテキストはバリデーションに基づいて自動表示
- デフォルトブロック:
signInTitle、emailField、passwordField、signInButton、resetPassword、gotoSignUp - 追加ユーティリティフィールド利用可能:
TextField、TimeField、CheckboxField、SelectField - CSSクラスはBEMスタイルの命名に従います:
nbb-signin、nbb-signin-signin-title、nbb-signin-email-fieldなど - デフォルト登録リンクは
/auth/signupを指します - デフォルトパスワードリセットリンクは
/auth/resetpasswordを指します
React、TypeScript、MUIを使用して❤️で構築されました。