サインアップブロック
SignUpコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルなサインアップフォームです。モダンなデザインパターン、フォームバリデーション、利用規約の同意、柔軟なカスタマイズオプションを備えた完全なユーザー登録インターフェースを提供します。
🚀 インストール
npm install @nodeblocks/frontend-signup-block@0.3.2
📖 使用方法
import {SignUp} from '@nodeblocks/frontend-signup-block';
- 基本的な使用方法
- 高度な使用方法
function BasicSignUp() {
return (
<SignUp
onChange={(setError, getValues, clearErrors) => {
console.log('フォーム値:', getValues());
const values = getValues();
if (!values.email) {
setError('email', {message: 'メールアドレスは必須です', type: 'required'});
} else {
clearErrors('email');
}
}}
onSubmit={formData => {
console.log('フォームが送信されました:', formData);
}}
style={{display: 'flex', flexDirection: 'column', gap: '16px'}}>
<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
style={{
maxWidth: '550px',
margin: '0 auto',
borderRadius: '20px',
border: '1px solid #e2e8f0',
padding: '40px',
boxShadow: '0 25px 50px rgba(102, 126, 234, 0.3)',
}}
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');
}
if (!values.agreesUserAgreement) {
setError('agreesUserAgreement', {message: '利用規約への同意が必要です', type: 'required'});
} else {
clearErrors('agreesUserAgreement');
}
if (!values.agreesPrivacyPolicy) {
setError('agreesPrivacyPolicy', {message: 'プライバシーポリシーへの同意が必要です', type: 'required'});
} else {
clearErrors('agreesPrivacyPolicy');
}
}}
onSubmit={formData => {
console.log('新規登録:', formData);
}}
>
{({defaultBlocks, defaultBlockOrder}) => {
return {
blocks: {
...defaultBlocks,
signUpTitle: {
...defaultBlocks.signUpTitle,
props: {
...defaultBlocks.signUpTitle.props,
style: {
color: 'black',
fontSize: '2.5rem',
fontWeight: 'bold',
textAlign: 'center',
marginBottom: '8px',
},
children: (
<div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '12px'}}>
<svg style={{width: '36px', height: '36px', color: 'rgb(105, 124, 213)'}} fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2ZM21 9V7L15 4L13 5.3V3.07C13 3.03 13 3 13 3H11C11 3 11 3.03 11 3.07V5.3L9 4L3 7V9H5C5.6 9 6 9.4 6 10V16C6 16.6 6.4 17 7 17H10V19H14V17H17C17.6 17 18 16.6 18 16V10C18 9.4 18.4 9 19 9H21Z" />
</svg>
<span>企業アカウント作成</span>
</div>
),
},
},
emailField: {
...defaultBlocks.emailField,
props: {
...defaultBlocks.emailField.props,
label: 'メールアドレス',
placeholder: '例: user@company.com',
style: {
background: 'rgba(255, 255, 255, 0.95)',
borderRadius: '12px',
fontSize: '16px',
},
},
},
passwordField: {
...defaultBlocks.passwordField,
props: {
...defaultBlocks.passwordField.props,
label: 'パスワード',
placeholder: '8文字以上の安全なパスワード',
style: {
background: 'rgba(255, 255, 255, 0.95)',
borderRadius: '12px',
fontSize: '16px',
},
},
},
termsOfUse: {
...defaultBlocks.termsOfUse,
props: {
...defaultBlocks.termsOfUse.props,
name: 'agreesUserAgreement',
label: (
<span style={{color: 'black', fontSize: '14px'}}>
<a
href="#terms"
style={{
color: 'rgb(105, 124, 213)',
textDecoration: 'none',
fontWeight: 'bold',
}}
>
利用規約
</a>
に同意します
</span>
),
},
},
privacyPolicy: {
...defaultBlocks.privacyPolicy,
props: {
...defaultBlocks.privacyPolicy.props,
name: 'agreesPrivacyPolicy',
label: (
<span style={{color: 'black', fontSize: '14px'}}>
<a
href="#privacy"
style={{
color: 'rgb(105, 124, 213)',
textDecoration: 'none',
fontWeight: 'bold',
}}
>
プライバシーポリシー
</a>
に同意します
</span>
),
},
},
signUpButton: {
...defaultBlocks.signUpButton,
props: {
...defaultBlocks.signUpButton.props,
children: (
<div>アカウントを作成</div>
),
},
},
gotoSignIn: {
...defaultBlocks.gotoSignIn,
props: {
...defaultBlocks.gotoSignIn.props,
style: {
textAlign: 'center',
},
children: (
<div style={{color: 'black', fontSize: '14px'}}>
<span>既にアカウントをお持ちの方は </span>
<a
href="#signin"
style={{
color: 'rgb(105, 124, 213)',
textDecoration: 'none',
fontWeight: 'bold',
}}
>
ログイン
</a>
</div>
),
},
},
},
blockOrder: defaultBlockOrder,
};
}}
</SignUp>
);
}
🔧 プロパティリファレンス
メインコンポーネントのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
onSubmit | SubmitHandler<T> | 必須 | 有効なデータでフォームが送信されたときにトリガーされるコールバック関数 |
onChange | (setError, getValues, clearErrors) => void | 必須 | フォーム値が変更されたときにトリガーされるコールバック関数。バリデーション用のフォーム制御関数を提供 |
defaultData | DefaultValues<T> | undefined | 初期レンダリング時にフィールドに設定するデフォルトフォーム値 |
data | T | undefined | 制御されたフォーム値 - 外部フォーム状態管理に使用 |
children | BlocksOverride | undefined | デフォルトレンダリングをオーバーライドするカスタムブロックコンポーネント |
className | string | undefined | フォームコンテナスタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML form要素プロパティを継承します。
サブコンポーネント
SignUpコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
SignUp.SignUpTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストから | タイトルコンテンツ |
size | enum | "2XL" | タイトルのタイポグラフィサイズ |
type | enum | "heading" | タイポグラフィタイプ |
color | enum | "low-emphasis" | タイトルのカラーテーマ |
weight | enum | "bold" | タイトルの太さ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
SignUp.EmailField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "email" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Email" | 入力の上に表示されるフィールドラベル |
placeholder | string | "Please enter your email" | フィールドが空のときに表示されるプレースホルダーテキスト |
isRequired | boolean | true | フィールドが必須かどうか(赤いアスタリスクを表示) |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML input要素プロパティを継承します。
SignUp.PasswordField
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "password" | フォームデータとバリデーションに使用されるフィールド名 |
label | string | "Password" | 入力の上に表示されるフィールドラベル |
placeholder | string | "Please enter your password" | フィールドが空のときに表示されるプレースホルダーテキスト |
inputType | string | "password" | 入力タイプ - 通常「password」または「text」 |
isRequired | boolean | true | フィールドが必須かどうか(赤いアスタリスクを表示) |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントは追加で一般的なHTML input要素プロパティを継承します。
SignUp.TermsOfUse
HTML input要素のすべてのプロパティを継承し、以下を追加します:
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "agreesUserAgreement" | フォームデータとバリデーションに使用されるフィールド名 |
label | ReactNode | デフォルト利用規約リンク | 利用規約チェックボックスラベルのコンテンツ - 通常リンクを含む |
isRequired | boolean | true | フィールドが必須かどうか(赤いアスタリスクを表示) |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
SignUp.PrivacyPolicy
HTML input要素のすべてのプロパティを継承し、以下を追加します:
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | "agreesPrivacyPolicy" | フォームデータとバリデーションに使用されるフィールド名 |
label | ReactNode | デフォルトプライバシーポリシーリンク | プライバシーポリシーチェックボックスラベルのコンテンツ - 通常リンクを含む |
isRequired | boolean | true | フィールドが必須かどうか(赤いアスタリスクを表示) |
isDisabled | boolean | undefined | 入力が無効かどうか |
errorText | string | undefined | 入力のエラーテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
SignUp.SignUpButton
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Sign Up" | ボタンテキストコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
fill | enum | "fill" | ボタンフィルスタイル |
icon | enum | undefined | ボタン左側のオプションアイコン |
iconColor | enum | undefined | 左側アイコンの色。提供されない場合、フィルタイプのデフォルト色が使用されます |
isDisabled | boolean | false | ボタンが無効で使用できないかどうか |
onClick | function | undefined | ボタンクリックを処理する関数 |
size | enum | "M" | ボタンの縦サイズ |
textAlign | enum | "center" | ボタン内でのアイコンとテキストの位置 |
textColor | enum | "default" | ボタンテキストの色 |
textEmphasis | boolean | false | ボタンテキストの太さ |
textSize | enum | "M" | ボタンテキストのサイズ |
type | enum | "submit" | ボタンの目的(htmlタイプに影響) |
SignUp.GotoSignIn
HTML div要素のすべてのプロパティを継承し(childrenを除く)、以下を追加します:
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | デフォルトサインインリンク | サインインリンクセクションのコンテンツ - 通常アンカータグを含む |
className | string | undefined | スタイリング用の追加CSSクラス名 |
🔧 TypeScript サポート
包括的な型定義による完全なTypeScriptサポート:
import {SignUp} from '@nodeblocks/frontend-signup-block';
//将来的にはreact-hook-formを使用せず、独自のフォーム処理を使用します
import {UseFormClearErrors, UseFormGetValues, UseFormSetError} from 'react-hook-form';
// デフォルトフォームデータ構造
interface DefaultSignUpFormData {
email?: string;
password?: string;
agreesPrivacyPolicy?: boolean;
agreesUserAgreement?: boolean;
}
// カスタムフィールドで拡張
interface CustomSignUpFormData extends DefaultSignUpFormData {
firstName?: string;
lastName?: string;
phone?: string;
}
const MySignUpForm = () => {
const handleSubmit = (formData: CustomSignUpFormData) => {
console.log('フォームが送信されました:', formData);
// フォーム送信を処理
};
const handleChange = (
setError: UseFormSetError<CustomSignUpFormData>,
getValues: UseFormGetValues<CustomSignUpFormData>,
clearErrors: UseFormClearErrors<CustomSignUpFormData>,
) => {
const values = getValues();
// カスタムバリデーション
if (values.email && !values.email.includes('@')) {
setError('email', {message: '無効なメールアドレス形式です'});
} else {
clearErrors('email');
}
};
return (
<SignUp<DefaultSignUpFormData>
onSubmit={handleSubmit}
onChange={handleChange}
defaultData={{email: 'user@example.com'}}>
<SignUp.SignUpTitle>アカウント作成</SignUp.SignUpTitle>
<SignUp.EmailField />
<SignUp.PasswordField />
<SignUp.TermsOfUse
name="agreesUserAgreement"
label={
<span>
<a href="#terms">利用規約</a>に同意します
</span>
}
/>
<SignUp.PrivacyPolicy
name="agreesPrivacyPolicy"
label={
<span>
<a href="#privacy">プライバシーポリシー</a>に同意します
</span>
}
/>
<SignUp.SignUpButton>登録</SignUp.SignUpButton>
<SignUp.GotoSignIn>
<span>
既にアカウントをお持ちですか? <a href="/signin">サインイン</a>
</span>
</SignUp.GotoSignIn>
</SignUp>
);
};
React、TypeScript、モダンなウェブ標準を使用して❤️で構築されました。