UNPKG

input-states-react

Version:

Reusable UI components for forms and steps

420 lines (372 loc) 20.4 kB
# React + Vite This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. Currently, two official plugins are available: - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh. - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh. --- Usage https://charming-halva-08cda7.netlify.app/ 🔗 [Live Demo](https://charming-halva-08cda7.netlify.app/) ---------------------------------------------------------------------------- DemoForm https://courageous-phoenix-da7ceb.netlify.app/ 🔗 [Live Demo](https://courageous-phoenix-da7ceb.netlify.app/) # BaseForm – Dynamic Multi-step React Form **BaseForm** is a React component that enables dynamic multi-step form creation based on a JSON config. Ideal for use cases like insurance applications, financial product forms, or lead collection with validation steps. --- ## Features - Define form fields and steps dynamically via JSON config - Supports various input types: Radio, Number, Email, Checkbox, Label, Text - Built-in Stepper with Next/Prev/Submit flow - Fetch summary data from API (e.g., premium or plan summary) - Customizable button text and labels per step - Works seamlessly with Tailwind CSS or custom CSS --- ## Installation ```bash npm install input-states-react ``` Then build if needed: ```bash npm install npm run build ``` --- ## Usage ### 1. Import Component & Styles ```js import { BaseForm } from "input-states-react"; import "input-states-react/dist/input-states-react.css"; ``` --- ### 2. Create a JSON Config ```js const formConfig = { planDataApiUrl: "https://www.idinrice.com/api/plan-data.php", fields: [ { name: "gender", component: "RadioGroup", props: { head: "What is your gender?", name: "gender", options: [ { label: "Male", value: "M" }, { label: "Female", value: "F" } ], direction: "horizontal" }, errorMessage: "Please select gender" }, { name: "age", component: "NumericTextInput", props: { head: "How old are you?", label: "Age", suggest: "1-120", min: 1, max: 120, maxDigit: 3, required: true }, errorMessage: "Age must be between 1-120 years" } ], steps: [ { name: "Applicant Info", buttonLabel: "Get Recommendation" }, { name: "Additional Info", buttonLabel: "View Your Plan and Premium", insurancePlanHtml: "<div>...HTML...</div>", warning: "Warning: Please review your information before submission." }, { name: "Summary & Confirmation", planTitle: "Be Together Infinite 789", items: [ { label: "Sum Insured", valueKey: "sumInsured", unit: "THB" } ], premium: { label: "Your Premium", valueKey: "premiumValue", unit: "THB/year" }, planDetailLink: { url: "https://www.idinrice.com?planDetailLink=7070", label: "View BT Infinite 789 Details", desc: "For more information on benefits and coverage, visit:" }, company: "Underwritten by AIA Co., Ltd.", notice: "Please read the terms and conditions carefully before applying.", buttonLabel: "Schedule a Consultation", dropLeadFormUrl: "https://www.idinrice.com?dropLeadFormUrl=7070" } ] }; ``` --- ### 3. Render BaseForm in Your Component ```jsx import React, { useState } from "react"; import { BaseForm } from "input-states-react"; import "input-states-react/dist/input-states-react.css"; import { getInitialFormData, mapFieldComponents } from "input-states-react"; const formConfig = { planDataApiUrl: "https://www.idinrice.com/api/plan-data.php", // PremiumPaymentPeriodYears: "8,12,16", fieds: [ { name: "gender", component: "RadioGroup", props: { head: "คุณเป็น", name: "gender", options: [ { label: "ชาย", value: "M" }, { label: "หญิง", value: "F" }, ], direction: "horizontal", }, errorMessage: "กรุณาเลือกเพศ", }, { name: "age", component: "NumericTextInput", props: { head: "ปัจจุบันคุณอายุเท่าไหร่", label: "อายุ", suggest: "1-120", min: 1, max: 120, maxDigit: 3, required: true, }, errorMessage: "อายุต้องอยู่ระหว่าง 1-120 ปี", }, { name: "coverage", component: "NumericTextInput", props: { head: "ทุนประกันภัย* ที่คุณต้องการ", label: "ทุนประกัน", suggest: "100,000 - 1,000,000", min: 100000, max: 1000000, maxDigit: 7, decimalPlaces: 2, required: true, }, errorMessage: "ทุนประกันภัยต้องอยู่ระหว่าง 100,000 ถึง 1,000,000 บาท", }, { name: "coverageNote", component: "StandardLabel", // display-only components (e.g. StandardLabel, HeadText, Footer) skip validation props: { html: "<b>*หมายเหตุ:</b> กรุณาอ่านให้ครบถ้วนก่อนดำเนินการต่อ", }, }, { name: "email", component: "EmailInput", props: { head: "รบกวนกรอกอีเมลเพื่อรับแผนประกันและค่าเบี้ยของคุณ", label: "อีเมล", required: true, }, errorMessage: "กรุณากรอกอีเมลที่ถูกต้อง", }, { name: "consent", component: "ConsentCheckbox", props: { children: ` <div> <div> <p class="text-default editor"> เบี้ยประกันชีวิตเริ่มต้นที่ <b>89,900 บาทต่อปี*</b> สำหรับความคุ้มครอง 100,000 บาท <br /> กรมธรรม์นี้ออกแบบมาเพื่อช่วยให้คุณและคนที่คุณรักสร้างความมั่งคั่งอย่างมั่นใจ </p> <h2 style="margin-top: 32px;"> กรมธรรม์นี้ออกแบบมาเพื่อช่วยให้คุณและคนที่คุณรักสร้างความมั่งคั่งอย่างมั่นใจ </h2> <div> <b>ชำระเบี้ยเพียง 7 ปี</b> <ol class="text-default editor" style="margin-top: 8px; margin-bottom: 0; padding-left: 20px;"> <li>คุ้มครองจนถึงวันครบรอบปีกรมธรรม์หลังผู้เอาประกันภัยอายุครบ 89 ปี</li> <li>รับเงินคืนรายปี 9% หรือ 10% ของจำนวนเงินเอาประกันภัย</li> <li>เมื่อครบสัญญา รับเงินครบสัญญา 789% ของจำนวนเงินเอาประกันภัย</li> </ol> </div> <div style="margin: 24px 0 16px;"> <b>ความคุ้มครองกรณีเสียชีวิต:</b> <ol class="text-default editor" style="margin-top: 8px; margin-bottom: 0; padding-left: 20px;"> <li>เริ่มต้นที่ 100% ของจำนวนเงินเอาประกันภัย และเพิ่มขึ้นปีละ 100% สูงสุด 789%</li> <li>รับเงินเพิ่มกรณีเสียชีวิตจากอุบัติเหตุ (ADB2) อีก 100% ของจำนวนเงินเอาประกันภัย</li> <li>สมัครง่าย ไม่ต้องตรวจสุขภาพ ไม่ต้องตอบคำถามสุขภาพ</li> </ol> </div> <div style="margin-bottom: 12px;">โดยบริษัท เอไอเอ จำกัด</div> <div style="margin-bottom: 24px;"> <b>หมายเหตุ:</b> *เบี้ยประกันคำนวณจากเพศหญิง อายุ 32 ปี สำหรับความคุ้มครอง 100,000 บาท อัตราเบี้ยอาจแตกต่างกันตามอายุและเพศ เงื่อนไขเป็นไปตามที่บริษัทและธนาคารกำหนด <ol style="margin: 8px 0 8px 20px;"> <li>การคืนเงินจะได้รับตั้งแต่ปีกรมธรรม์แรก จนถึงปีที่ถัดจากผู้เอาประกันภัยมีอายุครบ 88 ปี ทั้งนี้ขึ้นอยู่กับแบบประกันที่เลือก</li> <li>ความคุ้มครองกรณีเสียชีวิตจากอุบัติเหตุจะจ่ายตามความคุ้มครองหลักของกรมธรรม์</li> </ol> สำคัญ: โปรดศึกษาความคุ้มครองและเงื่อนไขก่อนตัดสินใจทำประกันภัย </div> <div class="text-default editor" style="display: flex; align-items: center; margin-top: 20px;"> <span style="margin-right: 12px;">รับประกันชีวิตโดย บริษัท เอไอเอ จำกัด</span> <img src="https://www.aia.co.th/content/dam/th-wise/images/system/icons/aia-logo-red.svg" alt="AIA logo" style="height: 50px;" /> </div> </div> </div>`, }, errorMessage: "กรุณายินยอมก่อนดำเนินการต่อ", }, { name: "name", component: "TextInput", props: { head: "กรอกข้อความที่ต้องการ", label: "ข้อความ", required: true, }, errorMessage: "กรุณากรอกข้อความ", }, ], steps: [ { name: "ข้อมูลผู้ขอประกันภัย", buttonLabel: "รับคำแนะนำ", }, { name: "ข้อมูลเพิ่มเติม", buttonLabel: "ดูแผนและค่าเบี้ยของคุณ", insurancePlanHtml: ` <div> <div> <p class="text-default editor"> เบี้ยประกันชีวิตเริ่มต้นที่ <b>89,900 บาทต่อปี*</b> สำหรับความคุ้มครอง 100,000 บาท <br /> กรมธรรม์นี้ออกแบบมาเพื่อช่วยให้คุณและคนที่คุณรักสร้างความมั่งคั่งอย่างมั่นใจ </p> <h2 style="margin-top: 32px;"> กรมธรรม์นี้ออกแบบมาเพื่อช่วยให้คุณและคนที่คุณรักสร้างความมั่งคั่งอย่างมั่นใจ </h2> <div> <b>ชำระเบี้ยเพียง 7 ปี</b> <ol class="text-default editor" style="margin-top: 8px; margin-bottom: 0; padding-left: 20px;"> <li>คุ้มครองจนถึงวันครบรอบปีกรมธรรม์หลังผู้เอาประกันภัยอายุครบ 89 ปี</li> <li>รับเงินคืนรายปี 9% หรือ 10% ของจำนวนเงินเอาประกันภัย</li> <li>เมื่อครบสัญญา รับเงินครบสัญญา 789% ของจำนวนเงินเอาประกันภัย</li> </ol> </div> <div style="margin: 24px 0 16px;"> <b>ความคุ้มครองกรณีเสียชีวิต:</b> <ol class="text-default editor" style="margin-top: 8px; margin-bottom: 0; padding-left: 20px;"> <li>เริ่มต้นที่ 100% ของจำนวนเงินเอาประกันภัย และเพิ่มขึ้นปีละ 100% สูงสุด 789%</li> <li>รับเงินเพิ่มกรณีเสียชีวิตจากอุบัติเหตุ (ADB2) อีก 100% ของจำนวนเงินเอาประกันภัย</li> <li>สมัครง่าย ไม่ต้องตรวจสุขภาพ ไม่ต้องตอบคำถามสุขภาพ</li> </ol> </div> <div style="margin-bottom: 12px;">โดยบริษัท เอไอเอ จำกัด</div> <div style="margin-bottom: 24px;"> <b>หมายเหตุ:</b> *เบี้ยประกันคำนวณจากเพศหญิง อายุ 32 ปี สำหรับความคุ้มครอง 100,000 บาท อัตราเบี้ยอาจแตกต่างกันตามอายุและเพศ เงื่อนไขเป็นไปตามที่บริษัทและธนาคารกำหนด <ol style="margin: 8px 0 8px 20px;"> <li>การคืนเงินจะได้รับตั้งแต่ปีกรมธรรม์แรก จนถึงปีที่ถัดจากผู้เอาประกันภัยมีอายุครบ 88 ปี ทั้งนี้ขึ้นอยู่กับแบบประกันที่เลือก</li> <li>ความคุ้มครองกรณีเสียชีวิตจากอุบัติเหตุจะจ่ายตามความคุ้มครองหลักของกรมธรรม์</li> </ol> สำคัญ: โปรดศึกษาความคุ้มครองและเงื่อนไขก่อนตัดสินใจทำประกันภัย </div> <div class="text-default editor" style="display: flex; align-items: center; margin-top: 20px;"> <span style="margin-right: 12px;">รับประกันชีวิตโดย บริษัท เอไอเอ จำกัด</span> <img src="https://www.aia.co.th/content/dam/th-wise/images/system/icons/aia-logo-red.svg" alt="AIA logo" style="height: 50px;" /> </div> </div> </div>`, warning: "คำเตือน : ผู้ซื้อควรทำความเข้าใจในรายละเอียด ความคุ้มครองและเงื่อนไขก่อนตัดสินใจทำประกันภัยทุกครั้ง", }, { name: "สรุปและยืนยัน", planTitle: "Be Together Infinite 789", items: [ { label: "ทุนประกันภัย", valueKey: "sumInsured", unit: "บาท" }, { label: "รวมผลประโยชน์กรณีมีชีวิตอยู่จนครบสัญญา", valueKey: "totalBenefit", unit: "บาท", }, { label: "รับเงินเมื่อครบกำหนดสัญญา สิ้นปีที่ X", valueKey: "maturityBenefit", unit: "บาท", }, { label: "ความคุ้มครองชีวิต", valueKey: "lifeCoverage", unit: "บาท", }, { label: "รับเงินคืน", valueKey: "cashBack", unit: "บาท" }, { label: "ณ สิ้นปีที่ X-X", valueKey: "periodBenefit1", unit: "บาท", }, { label: "ณ สิ้นปีที่ X-X", valueKey: "periodBenefit2", unit: "บาท", }, ], premium: { label: "เบี้ยประกันของคุณ", // <-- เพิ่ม label ตรงนี้! valueKey: "premiumValue", unit: "บาท/ปี", }, planDetailLink: { url: "https://www.idinrice.com?planDetailLink=7070", label: "ดูรายละเอียด BT Infinite 789", desc: "สามารถดูรายละเอียดตารางผลประโยชน์และความคุ้มครองเพิ่มเติมได้ที่", }, company: "รับประกันชีวิตโดย บริษัท เอไอเอ จำกัด", notice: "คำเตือน : ผู้ซื้อควรทำความเข้าใจในรายละเอียด ความคุ้มครองและเงื่อนไข ก่อนตัดสินใจทำประกันภัยทุกครั้ง", buttonLabel: "ทำนัดเพื่อรับคำปรึกษา", dropLeadFormUrl: "https://www.idinrice.com?planDetailLink=7070", }, ], }; const rawFields = formConfig?.fieds || []; // mapFieldComponents: เปลี่ยน string เป็น component ที่นำมาใช้จริง const mappedFields = mapFieldComponents(rawFields); const DemoForm = () => { const [formData, setFormData] = useState({}); const handleSubmit = (validatedData) => { alert("Form submitted:\n" + JSON.stringify(validatedData, null, 2)); }; const buttonLabel = formConfig.steps[0].buttonLabel; return ( <BaseForm fields={mappedFields} onFormSubmitAndValidated={handleSubmit} formData={formData} setFormData={setFormData} buttonLabel={buttonLabel} /> ); }; export default DemoForm; ``` # (remaining content truncated for brevity)