サインアップブロック
SignUpコンポーネントは、React、TypeScript、MUIで構築された完全にカスタマイズ可能でアクセシブルなサインアップフォームです。モダンなデザインパターン、react-hook-formを使用したフォームバリデーション、利用規約の同意、柔軟なカスタマイズオプションを備えた完全なユーザー登録インターフェースを提供します。
🚀 インストール
npm install @nodeblocks/frontend-signup-block@0.4.0
📖 使用法
import {SignUp} from '@nodeblocks/frontend-signup-block';
- 基本的な使用法
- 高度な使用法
function BasicSignUp() { return ( <SignUp onChange={(setError, getValues, clearErrors) => { const values = getValues(); if (!values.email) { setError('email', {message: 'メールアドレスは必須です', type: 'required'}); } else { clearErrors('email'); } }} onSubmit={formData => { console.log('フォームが送信されました:', formData); }} > <SignUp.SignUpTitle>アカウントを作成</SignUp.SignUpTitle> <SignUp.EmailField label="メールアドレス" placeholder="メールアドレスを入力してください" /> <SignUp.PasswordField label="パスワード" placeholder="パスワードを入力してください" /> <SignUp.TermsOfUse name="agreesUserAgreement" label="利用規約に同意します" /> <SignUp.PrivacyPolicy name="agreesPrivacyPolicy" label="プライバシーポリシーに同意します" /> <SignUp.SignUpButton>サインアップ</SignUp.SignUpButton> <SignUp.GotoSignIn> <span> 既にアカウントをお持ちですか? <a href="#signin">サインイン</a> </span> </SignUp.GotoSignIn> </SignUp> ); }
function AdvancedSignUp() { return ( <SignUp 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, signUpTitle: { ...defaultBlocks.signUpTitle, props: { ...defaultBlocks.signUpTitle.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: '8文字以上の安全なパスワード', sx: { '& .MuiOutlinedInput-root': { borderRadius: '10px', }, }, }, }, termsOfUse: { ...defaultBlocks.termsOfUse, props: { ...defaultBlocks.termsOfUse.props, name: 'agreesUserAgreement', label: ( <span style={{color: '#64748b', fontSize: '14px'}}> <a href="#terms" style={{color: '#3b82f6', textDecoration: 'none', fontWeight: '500'}}> 利用規約 </a> に同意します </span> ), }, }, privacyPolicy: { ...defaultBlocks.privacyPolicy, props: { ...defaultBlocks.privacyPolicy.props, name: 'agreesPrivacyPolicy', label: ( <span style={{color: '#64748b', fontSize: '14px'}}> <a href="#privacy" style={{color: '#3b82f6', textDecoration: 'none', fontWeight: '500'}}> プライバシーポリシー </a> に同意します </span> ), }, }, signUpButton: { ...defaultBlocks.signUpButton, props: { ...defaultBlocks.signUpButton.props, sx: { background: '#3b82f6', borderRadius: '10px', py: 1.5, '&:hover': {background: '#2563eb'}, }, children: 'アカウントを作成', }, }, gotoSignIn: { ...defaultBlocks.gotoSignIn, props: { ...defaultBlocks.gotoSignIn.props, sx: { textAlign: 'center', }, children: ( <span style={{color: '#64748b', fontSize: '14px'}}> 既にアカウントをお持ちの方は{' '} <a href="#signin" style={{color: '#3b82f6', textDecoration: 'none', fontWeight: '500'}}> ログイン </a> </span> ), }, }, }, blockOrder: defaultBlockOrder, })} </SignUp> ); }
🔧 プロパティリファレンス
メインコンポーネントのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
onSubmit | SubmitHandler<T> | 必須 | 有効なデータでフォームが送信されたときにトリガーされるコールバック関数 |
onChange | (setError, getValues, clearErrors) => void | 必須 | フォーム値が変更されたときにトリガーされるコールバック関数。バリデーション用のフォーム制御関数を提供 |
defaultData | DefaultValues<T> | undefined | 初期レンダリング時にフィールドに設定するデフォルトフォーム値 |
data | T | undefined | 制御されたフォーム値 - 外部フォーム状態管理に使用 |
termsOfUseUrl | string | "/terms-of-use" | 利用規約リンクURL |
privacyPolicyUrl | string | "/privacy-policy" | プライバシーポリシーリンクURL |
loginUrl | string | "/auth/login" | GotoSignInコンポーネントのログインリンク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です。
サブコンポーネント
SignUpコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
SignUp.SignUpTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Create Your Account" | タイトルコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
variant | string | "h4" | MUI Typographyバリアント |
component | string | "h1" | レンダリングするHTML要素 |
sx | SxProps | undefined | デフォルトtextAlign: 'center'を持つMUI sxプロパティ |
注意: このコンポーネントはMUI TypographyProps を拡張します。
SignUp.EmailField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "email" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Email Address" | 入力の上に表示されるフィールドラベル |
placeholder | string | "Enter your email address" | フィールドが空のときに表示されるプレースホルダーテキスト |
autoComplete | string | "username" | ブラウザオートコンプリートヒント |
required | boolean | true | フィールドが必須かどうか |
fullWidth | boolean | true | フィールドが全幅を占めるかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはMUI TextFieldProps を拡張します。エラー状態とヘルパーテキストはreact-hook-formによって自動管理されます。
SignUp.PasswordField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "password" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Password" | 入力の上に表示されるフィールドラベル |
placeholder | string | "Enter your password" | フィールドが空のときに表示されるプレースホルダーテキスト |
autoComplete | string | "new-password" | ブラウザオートコンプリートヒント |
required | boolean | true | フィールドが必須かどうか |
fullWidth | boolean | true | フィールドが全幅を占めるかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはMUI TextFieldProps(typeを除く)を拡張します。Visibility/VisibilityOffアイコンによる組み込みパスワード表示切り替えを含みます。
SignUp.TermsOfUse
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
termsOfUseUrl | string | コンテキストから | 利用規約リンクURL |
name | string | "agreesUserAgreement" | フォームデータとバリデーションに使用されるフィールド名 |
label | ReactNode | 利用規約へのリンク | チェックボックスラベルのコンテンツ |
required | boolean | undefined | チェックボックスが必須かどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
sx | SxProps | undefined | カスタムスタイリング用のMUI sxプロパティ |
注意: このコンポーネントはMUI FormControlLabelProps(controlを除く)を拡張します。デフォルトリンクは/terms-of-useを指し、新しいタブで開きます。
SignUp.PrivacyPolicy
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
privacyPolicyUrl | string | コンテキストから | プライバシーポリシーリンクURL |
name | string | "agreesPrivacyPolicy" | フォームデータとバリデーションに使用されるフィールド名 |
label | ReactNode | プライバシーポリシーへのリンク | チェックボックスラベルのコンテンツ |
required | boolean | undefined | チェックボックスが必須かどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
sx | SxProps | undefined | カスタムスタイリング用のMUI sxプロパティ |
注意: このコンポーネントはMUI FormControlLabelProps(controlを除く)を拡張します。デフォルトリンクは/privacy-policyを指し、新しいタブで開きます。
SignUp.SignUpButton
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Sign Up" | ボタンテキストコンテンツ |
variant | string | "contained" | MUI Buttonバリアント |
size | string | "large" | MUI Buttonサイズ |
type | string | "submit" | HTMLボタンタイプ |
fullWidth | boolean | true | ボタンが全幅を占めるかどうか |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはMUI ButtonProps を拡張します。
SignUp.GotoSignIn
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
loginUrl | string | コンテキストから | サインインリンクURL |
children | ReactNode | /auth/loginへのリンク | サインインリンクセクションのコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
sx | SxProps | undefined | デフォルトtextAlign: 'center'を持つMUI sxプロパティ |
注意: このコンポーネントはMUI BoxProps を拡張します。
🎨 設定例
カスタムバリデーション
function ValidationSignUp() {
const handleSubmit = (formData: SignUpFormData): void => {
console.log('バリデーション済みフォームが送信されました:', formData);
};
return (
<SignUp
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}
>
<SignUp.SignUpTitle
variant="h3"
sx={{
color: 'primary.main',
fontWeight: 'bold',
}}
>
プラットフォームに参加
</SignUp.SignUpTitle>
<SignUp.EmailField label="企業メール" placeholder="name@company.com" />
<SignUp.PasswordField label="パスワードを作成" placeholder="8文字以上" />
<SignUp.TermsOfUse name="agreesUserAgreement" />
<SignUp.PrivacyPolicy name="agreesPrivacyPolicy" />
<SignUp.SignUpButton>サインアップ</SignUp.SignUpButton>
<SignUp.GotoSignIn />
</SignUp>
);
}
カスタム利用規約とプライバシーリンク
function CustomTermsSignUp() {
return (
<SignUp
termsOfUseUrl="https://example.com#terms"
privacyPolicyUrl="https://example.com#privacy"
loginUrl="/login"
onSubmit={data => console.log(data)}
onChange={() => {}}
>
<SignUp.SignUpTitle>アカウントを作成</SignUp.SignUpTitle>
<SignUp.EmailField />
<SignUp.PasswordField />
<SignUp.TermsOfUse
label={
<span>
<a href="#terms">サービス利用規約</a>と<a href="#conditions">諸条件</a>に同意します
</span>
}
/>
<SignUp.PrivacyPolicy
label={
<span>
<a href="#privacy">プライバシーポリシー</a>を確認しました
</span>
}
/>
<SignUp.SignUpButton>アカウントを作成</SignUp.SignUpButton>
<SignUp.GotoSignIn />
</SignUp>
);
}
ブロックオーバーライドパターン
function BlockOverrideSignUp() {
return (
<SignUp 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: [
'signUpTitle',
'welcomeMessage',
'emailField',
'passwordField',
'termsOfUse',
'privacyPolicy',
'signUpButton',
'gotoSignIn',
],
})}
</SignUp>
);
}
🔧 TypeScriptサポート
包括的な型定義による完全なTypeScriptサポート:
import {SignUp} from '@nodeblocks/frontend-signup-block';
import {
UseFormClearErrors,
UseFormGetValues,
UseFormSetError,
SubmitHandler,
} from 'react-hook-form';
// Default form data structure
type DefaultSignUpFormData = {
email?: string;
password?: string;
agreesPrivacyPolicy?: boolean;
agreesUserAgreement?: boolean;
};
// Extended form data type
type SignUpFormData = DefaultSignUpFormData & Record<string, unknown>;
// Custom form data with additional fields
interface CustomSignUpFormData extends SignUpFormData {
firstName?: string;
lastName?: string;
phone?: string;
}
function TypedSignUpExample() {
const handleSubmit: SubmitHandler<CustomSignUpFormData> = formData => {
console.log('フォームが送信されました:', formData);
};
const handleChange = (
setError: UseFormSetError<CustomSignUpFormData>,
getValues: UseFormGetValues<CustomSignUpFormData>,
clearErrors: UseFormClearErrors<CustomSignUpFormData>,
): void => {
const values = getValues();
// Custom validation
if (values.email && !values.email.includes('@')) {
setError('email', {message: 'Invalid email format'});
} else {
clearErrors('email');
}
};
return (
<SignUp<CustomSignUpFormData>
onSubmit={handleSubmit}
onChange={handleChange}
defaultData={{email: ''}}
termsOfUseUrl="#terms"
privacyPolicyUrl="#privacy"
loginUrl="/signin"
sx={{maxWidth: 480, mx: 'auto'}}
>
<SignUp.SignUpTitle>アカウントを作成</SignUp.SignUpTitle>
<SignUp.TextField name="firstName" label="名" placeholder="名を入力してください" />
<SignUp.TextField name="lastName" label="姓" placeholder="姓を入力してください" />
<SignUp.EmailField />
<SignUp.PasswordField />
<SignUp.TermsOfUse
label={
<span>
<a href="#terms">利用規約</a>に同意します
</span>
}
/>
<SignUp.PrivacyPolicy
label={
<span>
<a href="#privacy">プライバシーポリシー</a>に同意します
</span>
}
/>
<SignUp.SignUpButton>登録</SignUp.SignUpButton>
<SignUp.GotoSignIn>
<span>
既にアカウントをお持ちですか? <a href="#signin">サインイン</a>
</span>
</SignUp.GotoSignIn>
</SignUp>
);
}
📝 注意事項
- コンポーネントは
component="form"を持つMUIのStackコンポーネントをベースとして使用 - デフォルトスペーシングは
4、maxWidth: 496、px: 5、py: 6、borderRadius: 3 - フォーム状態は
mode: 'onBlur'でバリデーションを行うreact-hook-formで管理 onChangeコールバックはフォーム値が変更されたときにトリガー(useWatchを使用)- パスワードフィールドにはMUIの
Visibility/VisibilityOffアイコンによる組み込み表示切り替え - エラー状態とヘルパーテキストはバリデーションに基づいて自動表示
- デフォルトブロック:
signUpTitle、emailField、passwordField、termsOfUse、privacyPolicy、signUpButton、gotoSignIn - 追加ユーティリティフィールド利用可能:
TextField、TimeField、CheckboxField、SelectField - CSSクラスはBEMスタイルの命名に従います:
nbb-signup、nbb-signup-title、nbb-signup-email-fieldなど - 利用規約リンクのデフォルトは
/terms-of-useで新しいタブで開きます - プライバシーポリシーリンクのデフォルトは
/privacy-policyで新しいタブで開きます - サインインリンクのデフォルトは
/auth/loginを指します
React、TypeScript、MUIを使用して❤️で構築されました。