Basic Information Block
The BasicInformation Component is a fully customizable and accessible form for collecting user's basic information built with React and TypeScript. It provides a complete address and contact information interface with modern design patterns, form validation, and flexible customization options.
๐ Installationโ
npm install @nodeblocks/frontend-basic-information-block
๐ Usageโ
import {BasicInformation} from '@nodeblocks/frontend-basic-information-block';
- Basic Usage
- Advanced Usage
function BasicInformationForm() { return ( <BasicInformation onChange={(setError, getValues) => { console.log('Form values:', getValues()); const values = getValues(); if (!values.NameInput) { setError('NameInput', {message: 'Name is required', type: 'required'}); } }} onSubmit={formData => { console.log('Form submitted:', formData); }} onInvalid={errors => { console.log('Form validation errors:', errors); }}> <BasicInformation.Title>Basic Information</BasicInformation.Title> <BasicInformation.Subtitle>Please fill in your basic information</BasicInformation.Subtitle> <BasicInformation.NameInput /> <BasicInformation.FuriganaInput /> <BasicInformation.PostalCodeInput /> <BasicInformation.PrefectureSelect /> <BasicInformation.CityInput /> <BasicInformation.AddressInput /> <BasicInformation.PhoneInput /> <BasicInformation.SubmitButton>Submit</BasicInformation.SubmitButton> </BasicInformation> ); }
function AdvancedBasicInformationForm() { return ( <BasicInformation style={{maxWidth: '1000px', margin: '0 auto'}} onChange={(setError, getValues) => { const values = getValues(); if (!values.NameInput) { setError('NameInput', {message: 'ๆฐๅใฏๅฟ ้ ้ ็ฎใงใ', type: 'required'}); } if (values.PhoneInput && !/^[\d-+()]*$/.test(values.PhoneInput)) { setError('PhoneInput', {message: 'ๆๅนใช้ป่ฉฑ็ชๅทใๅ ฅๅใใฆใใ ใใ', type: 'pattern'}); } }} onSubmit={formData => { console.log('Form submitted:', formData); }} onInvalid={errors => { console.log('Form validation errors:', errors); }} > {({defaultBlocks, defaultBlockOrder}) => { return { blocks: { ...defaultBlocks, title: { ...defaultBlocks.title, props: { ...defaultBlocks.title.props, style: { fontSize: '2rem', fontWeight: 'bold', textAlign: 'center', marginBottom: '8px', background: 'linear-gradient(135deg, #3B82F6, #8B5CF6)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text', }, children: 'ใใญใใฃใผใซไฝๆ', }, }, subtitle: { ...defaultBlocks.subtitle, props: { ...defaultBlocks.subtitle.props, style: {textAlign: 'center', color: '#6B7280', marginBottom: '2rem'}, children: ( <div style={{display: 'flex', flexDirection: 'column', gap: '1rem'}}> <p>ใๅฎขๆงใฎๅบๆฌๆ ๅ ฑใใๅ ฅๅใใ ใใ</p> <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px'}}> <div style={{display: 'flex', alignItems: 'center', gap: '4px'}}> <div style={{ width: '32px', height: '32px', backgroundColor: '#3B82F6', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '14px', fontWeight: '500', }} > 1 </div> <span style={{fontSize: '14px', fontWeight: '500', color: '#3B82F6'}}>ๅบๆฌๆ ๅ ฑ</span> </div> <div style={{width: '48px', height: '2px', backgroundColor: '#D1D5DB'}}></div> <div style={{display: 'flex', alignItems: 'center', gap: '4px'}}> <div style={{ width: '32px', height: '32px', backgroundColor: '#D1D5DB', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#6B7280', fontSize: '14px', fontWeight: '500', }} > 2 </div> <span style={{fontSize: '14px', color: '#6B7280'}}>่ฉณ็ดฐ่จญๅฎ</span> </div> <div style={{width: '48px', height: '2px', backgroundColor: '#D1D5DB'}}></div> <div style={{display: 'flex', alignItems: 'center', gap: '4px'}}> <div style={{ width: '32px', height: '32px', backgroundColor: '#D1D5DB', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#6B7280', fontSize: '14px', fontWeight: '500', }} > 3 </div> <span style={{fontSize: '14px', color: '#6B7280'}}>ๅฎไบ</span> </div> </div> </div> ), }, }, nameInput: { ...defaultBlocks.nameInput, props: { ...defaultBlocks.nameInput.props, label: 'ๆฐๅ', placeholder: 'ไพ: ๅฑฑ็ฐ ๅคช้', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '24px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, }, }, furiganaInput: { ...defaultBlocks.furiganaInput, props: { ...defaultBlocks.furiganaInput.props, label: 'ใใชใฌใ', placeholder: 'ไพ: ใคใใ ใฟใญใฆ', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '24px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, }, }, postalCodeInput: { ...defaultBlocks.postalCodeInput, props: { ...defaultBlocks.postalCodeInput.props, label: '้ตไพฟ็ชๅท', placeholder: 'ไพ: 123-4567', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '24px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, }, }, prefectureSelect: { ...defaultBlocks.prefectureSelect, props: { ...defaultBlocks.prefectureSelect.props, label: '้ฝ้ๅบ็', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '24px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, selectOptionValues: [ {value: 'tokyo', label: 'ๆฑไบฌ้ฝ'}, {value: 'osaka', label: 'ๅคง้ชๅบ'}, {value: 'kanagawa', label: '็ฅๅฅๅท็'}, {value: 'saitama', label: 'ๅผ็็'}, {value: 'chiba', label: 'ๅ่็'}, ], }, }, cityInput: { ...defaultBlocks.cityInput, props: { ...defaultBlocks.cityInput.props, label: 'ๅธๅบ็บๆ', placeholder: 'ไพ: ๆธ่ฐทๅบ', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '24px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, }, }, addressInput: { ...defaultBlocks.addressInput, props: { ...defaultBlocks.addressInput.props, label: '็บๅใป็ชๅฐใปๅปบ็ฉ', placeholder: 'ไพ: ้็ๅ1-2-3 ใใซๅ 4้', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '24px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, }, }, phoneInput: { ...defaultBlocks.phoneInput, props: { ...defaultBlocks.phoneInput.props, label: '้ฃ็ตกๅ ้ป่ฉฑ็ชๅท', placeholder: 'ไพ: 03-1234-5678', style: { background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '12px', border: '2px solid #e2e8f0', padding: '16px', marginBottom: '32px', transition: 'all 0.2s ease', boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)', }, }, }, submitButton: { ...defaultBlocks.submitButton, props: { ...defaultBlocks.submitButton.props, style: { width: '100%', padding: '16px 32px', background: 'linear-gradient(135deg, #3B82F6, #8B5CF6)', color: 'white', fontWeight: 'bold', borderRadius: '12px', border: 'none', boxShadow: '0 10px 25px rgba(0, 0, 0, 0.15)', transition: 'all 0.2s ease', cursor: 'pointer', }, onMouseEnter: e => { e.target.style.background = 'linear-gradient(135deg, #2563EB, #7C3AED)'; e.target.style.transform = 'translateY(-2px)'; e.target.style.boxShadow = '0 15px 35px rgba(0, 0, 0, 0.2)'; }, onMouseLeave: e => { e.target.style.background = 'linear-gradient(135deg, #3B82F6, #8B5CF6)'; e.target.style.transform = 'translateY(0)'; e.target.style.boxShadow = '0 10px 25px rgba(0, 0, 0, 0.15)'; }, children: ( <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px'}}> <span>ๆฌกใฎในใใใใธ้ฒใ</span> <svg style={{width: '20px', height: '20px'}} fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 7l5 5m0 0l-5 5m5-5H6" /> </svg> </div> ), }, }, }, blockOrder: defaultBlockOrder, }; }} </BasicInformation> ); }
๐ง Props Referenceโ
Main Component Propsโ
The main BasicInformation
component inherits all props from the HTML form
element (except onSubmit
, onChange
, and children
which are overridden) and adds:
Prop | Type | Default | Description |
---|---|---|---|
onSubmit | (data: T) => void | Required | Callback function triggered when form is submitted with valid data |
onChange | (setError, getValues) => void | Required | Callback function triggered when form values change. Provides form control functions for validation |
onInvalid | (errors: FieldErrors<T>) => void | Required | Callback function triggered when form submission fails validation |
defaultValues | DefaultValues<T> | undefined | Default form values to populate fields on initial render |
children | BlocksOverride | undefined | Custom block components to override default rendering |
className | string | undefined | Additional CSS class name for styling the form container |
Sub-Componentsโ
The BasicInformation component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.
BasicInformation.Titleโ
Inherits all props from the HTML h2
element and adds:
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | "ๅบๆฌๆ
ๅ ฑ" | Content to display as the title |
BasicInformation.Subtitleโ
Inherits all props from the HTML div
element and adds:
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Default required fields message | Content to display as the subtitle - typically shows required field information |
BasicInformation.NameInputโ
Uses deepMerge
to combine default field options with passed props. Inherits all props from the internal Input
component and adds:
| Prop | Type | Default | Description |
|------|------|---------|-------------|s
| name
| string
| "NameInput"
| Field name for form data |
| className
| string
| undefined
| Additional CSS class name for styling |
| errorText
| string
| undefined
| Error text for the input |
| isDisabled
| boolean
| undefined
| Whether the input is disabled |
| isRequired
| boolean
| undefined
| Whether the input is required |
| label
| string
| "ๆฐๅ"
| Label of the input field |
| labelWeight
| enum
| "bold"
| Label weight |
| onOperationClick
| () => void
| undefined
| Operation onClick callback |
| postfixText
| string
| undefined
| Text to place after the component |
| showPassword
| boolean
| undefined
| Whether to show password |
Note: This component additional inherits some common HTML input
element props.
BasicInformation.FuriganaInputโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | "FuriganaInput" | Field name for form data |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | "ใใชใฌใ" | Label of the input field |
labelWeight | enum | "bold" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input
element props.
BasicInformation.PostalCodeInputโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | "PostalCodeInput" | Field name for form data |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | "้ตไพฟ็ชๅท" | Label of the input field |
labelWeight | enum | "bold" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input
element props.
BasicInformation.PrefectureSelectโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | "PrefectureSelect" | Field name for form data |
label | string | "้ฝ้ๅบ็" | Field label |
labelWeight | enum | "bold" | Label weight |
selectOptionValues | Array<{value: string, label: string}> | [] | Array of prefecture options |
isRequired | boolean | undefined | Whether the field is required |
isDisabled | boolean | undefined | Whether the input is disabled |
errorText | string | undefined | Error text for the input |
className | string | undefined | Additional CSS class name for styling |
Note: This component additional inherits some common HTML select
element props.
BasicInformation.CityInputโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | "CityInput" | Field name for form data |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | "ๅธๅบ็บๆ" | Label of the input field |
labelWeight | enum | "bold" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input
element props.
BasicInformation.AddressInputโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | "AddressInput" | Field name for form data |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | "็บๅใป็ชๅฐใปๅปบ็ฉ" | Label of the input field |
labelWeight | enum | "bold" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
Note: This component additional inherits some common HTML input
element props.
BasicInformation.PhoneInputโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | "PhoneInput" | Field name for form data |
className | string | undefined | Additional CSS class name for styling |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | "้ฃ็ตกๅ
้ป่ฉฑ็ชๅท" | Label of the input field |
labelWeight | enum | "bold" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
inputMode | string | "numeric" | Input mode for mobile keyboards |
Note: This component additional inherits some common HTML input
element props.
BasicInformation.SubmitButtonโ
Inherits all props from the Button
component from @basaldev/blocks-frontend-framework
and adds:
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | "ๆฌกใธ" | Text to place inside the button |
className | string | undefined | Additional CSS class name for styling |
fill | enum | "fill" | Button fill style |
icon | enum | undefined | Optional icon for the left-hand side of the button |
iconColor | enum | undefined | Color for the left-hand side icon. When not provided, a default color for the fill type will be used. |
isDisabled | boolean | false | Whether the button is disabled and cannot be used |
onClick | function | undefined | Function to handle button click |
size | enum | "M" | Button vertical size |
textAlign | enum | "center" | Button icon and text positioning within the button |
textColor | enum | "default" | Button text color |
textEmphasis | boolean | false | Button text weight |
textSize | enum | "M" | Button text size |
type | enum | "submit" | Button purpose (affects html type) |
Note: This component additional inherits some common HTML button
element props.
Additional Field Componentsโ
The component also provides additional field types that can be used in custom forms:
BasicInformation.Inputโ
Prop | Type | Default | Description |
---|---|---|---|
name | string | Required | Field name for form data |
errorText | string | undefined | Error text for the input |
isDisabled | boolean | undefined | Whether the input is disabled |
isRequired | boolean | undefined | Whether the input is required |
label | string | Required | Label of the input field |
labelWeight | enum | "regular" | Label weight |
onOperationClick | () => void | undefined | Operation onClick callback |
postfixText | string | undefined | Text to place after the component |
showPassword | boolean | undefined | Whether to show password |
๐ง TypeScript Supportโ
Full TypeScript support with comprehensive type definitions:
import {BasicInformation} from '@nodeblocks/frontend-basic-information-block';
//in future we will not use react-hook-form, we will use our own form handling
import {FieldErrors, UseFormGetValues, UseFormSetError} from 'react-hook-form';
// Default form data structure
interface DefaultBasicInformationFormData {
NameInput: string;
FuriganaInput: string;
PostalCodeInput: string;
PrefectureSelect: string;
CityInput: string;
AddressInput: string;
PhoneInput: string;
}
// Extend with custom fields (component uses union type)
const MyBasicInformationForm = () => {
const handleSubmit = (formData: DefaultBasicInformationFormData) => {
console.log('Form submitted:', formData);
// Handle form submission
};
const handleInvalid = (errors: FieldErrors<DefaultBasicInformationFormData>) => {
console.log('Validation errors:', errors);
// Handle validation errors
};
const handleChange = (
setError: UseFormSetError<DefaultBasicInformationFormData>,
getValues: UseFormGetValues<DefaultBasicInformationFormData>,
) => {
const values = getValues();
// Custom validation
if (values.PhoneInput && values.PhoneInput.length < 10) {
setError('PhoneInput', {message: 'Phone number too short'});
}
};
return (
<BasicInformation<DefaultBasicInformationFormData>
onSubmit={handleSubmit}
onInvalid={handleInvalid}
onChange={handleChange}
defaultValues={{NameInput: 'John Doe'}}>
<BasicInformation.Title>Basic Information</BasicInformation.Title>
<BasicInformation.Subtitle>Please provide your details</BasicInformation.Subtitle>
<BasicInformation.NameInput />
<BasicInformation.FuriganaInput />
<BasicInformation.PostalCodeInput />
<BasicInformation.PrefectureSelect />
<BasicInformation.CityInput />
<BasicInformation.AddressInput />
<BasicInformation.PhoneInput />
<BasicInformation.SubmitButton>Submit</BasicInformation.SubmitButton>
</BasicInformation>
);
};
Built with โค๏ธ using React, TypeScript, and modern web standards.