@kadconsulting/dry
Version:
KAD Reusable Component Library
577 lines • 16.9 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import FormBuilder from './FormBuilder';
export default {
title: 'Components/Forms/FormBuilder',
component: FormBuilder,
argTypes: {
fields: {
control: 'object',
description: 'Array of form field configurations',
},
onSubmit: { action: 'submitted' },
},
};
const Template = (args) => (_jsx(FormBuilder, { ...args }));
export const Default = Template.bind({});
Default.args = {
fields: [
{
name: 'name',
label: 'Name',
type: 'text',
validation: { required: true },
},
{
name: 'email',
label: 'Email',
type: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
},
],
onSubmit: (data) => console.log(data),
};
export const AllFieldTypes = Template.bind({});
AllFieldTypes.args = {
fields: [
{
name: 'text',
Label: 'Text Input',
inputType: 'text',
validation: { required: true },
placeholder: 'Enter text',
},
{
name: 'number',
Label: 'Number Input',
inputType: 'number',
validation: { required: true },
min: 0,
max: 100,
placeholder: 'Enter a number',
},
{
name: 'email',
Label: 'Email Input',
inputType: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
placeholder: 'Enter your email',
},
{
name: 'password',
Label: 'Password Input',
inputType: 'password',
validation: { required: true, minLength: 8 },
placeholder: 'Enter your password',
},
{
name: 'textarea',
label: 'Textarea',
type: 'textarea',
validation: { required: true, maxLength: 500 },
placeholder: 'Enter your message',
},
{
name: 'checkbox',
type: 'checkbox',
LabelContent: 'I agree to the terms and conditions',
},
{
name: 'checkboxGroup',
type: 'checkboxGroup',
options: [
{ value: 'option1', LabelContent: 'Option 1' },
{ value: 'option2', LabelContent: 'Option 2' },
{ value: 'option3', LabelContent: 'Option 3' },
],
},
{
name: 'radio',
type: 'radioGroup',
options: [
{ value: 'optionA', text: 'Option A' },
{ value: 'optionB', text: 'Option B' },
{ value: 'optionC', text: 'Option C' },
],
},
{
name: 'toggle',
type: 'toggle',
text: 'Enable feature',
},
{
name: 'select',
Label: 'Select Dropdown',
inputType: 'select',
options: [
{ label: 'Choice 1', value: 'choice1' },
{ label: 'Choice 2', value: 'choice2' },
{ label: 'Choice 3', value: 'choice3' },
],
},
],
onSubmit: (data) => console.log(data),
};
export const WithValidation = Template.bind({});
WithValidation.args = {
fields: [
{
name: 'username',
Label: 'Username',
inputType: 'text',
validation: { required: true, minLength: 3, maxLength: 20 },
},
{
name: 'email',
Label: 'Email',
inputType: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
},
{
name: 'age',
Label: 'Age',
inputType: 'number',
validation: { required: true },
min: 18,
max: 99,
},
{
name: 'password',
Label: 'Password',
inputType: 'password',
validation: {
required: true,
minLength: 8,
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/,
},
},
],
onSubmit: (data) => console.log(data),
};
export const NestedFields = Template.bind({});
NestedFields.args = {
fields: [
{
name: 'personalInfo',
Label: 'Personal Information',
type: 'section',
fields: [
{
name: 'firstName',
Label: 'First Name',
inputType: 'text',
validation: { required: true },
},
{
name: 'lastName',
Label: 'Last Name',
inputType: 'text',
validation: { required: true },
},
{
name: 'dateOfBirth',
Label: 'Date of Birth',
inputType: 'date',
validation: { required: true },
},
],
},
{
name: 'contactInfo',
Label: 'Contact Information',
type: 'section',
fields: [
{
name: 'email',
Label: 'Email',
inputType: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
},
{
name: 'phone',
Label: 'Phone',
inputType: 'tel',
validation: { required: true, pattern: /^\d{10}$/ },
},
],
},
],
onSubmit: (data) => console.log(data),
};
export const ConditionalFields = Template.bind({});
ConditionalFields.args = {
fields: [
{
name: 'havePets',
type: 'radioGroup',
options: [
{ value: 'yes', text: 'Yes' },
{ value: 'no', text: 'No' },
],
},
{
name: 'petType',
Label: 'What type of pet do you have?',
inputType: 'select',
options: [
{ label: 'Dog', value: 'dog' },
{ label: 'Cat', value: 'cat' },
{ label: 'Other', value: 'other' },
],
condition: (formData) => formData.havePets === 'yes',
},
{
name: 'petName',
Label: "Pet's name",
inputType: 'text',
condition: (formData) => formData.havePets === 'yes',
},
],
onSubmit: (data) => console.log(data),
};
export const DynamicFields = Template.bind({});
DynamicFields.args = {
fields: [
{
name: 'name',
Label: 'Name',
inputType: 'text',
validation: { required: true },
},
{
name: 'email',
Label: 'Email',
inputType: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
},
{
name: 'phones',
Label: 'Phone Numbers',
type: 'dynamic',
template: {
name: 'phone',
Label: 'Phone',
inputType: 'tel',
validation: { required: true, pattern: /^\d{10}$/ },
},
min: 1,
max: 3,
},
],
onSubmit: (data) => console.log(data),
};
export const CustomLayout = Template.bind({});
CustomLayout.args = {
fields: [
{
name: 'firstName',
Label: 'First Name',
inputType: 'text',
validation: { required: true },
},
{
name: 'lastName',
Label: 'Last Name',
inputType: 'text',
validation: { required: true },
},
{
name: 'email',
Label: 'Email',
inputType: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
},
{
name: 'message',
label: 'Message',
type: 'textarea',
validation: { required: true },
},
],
layout: {
type: 'grid',
columns: 2,
fields: ['firstName', 'lastName', 'email', 'message'],
},
onSubmit: (data) => console.log(data),
};
export const WithCustomStyles = Template.bind({});
WithCustomStyles.args = {
...Default.args,
customStyles: {
form: { backgroundColor: '#f0f0f0', padding: '20px', borderRadius: '8px' },
field: { marginBottom: '15px' },
label: { color: '#333', fontWeight: 'bold' },
input: { borderColor: '#007bff', borderRadius: '4px' },
button: {
backgroundColor: '#007bff',
color: 'white',
padding: '10px 20px',
borderRadius: '4px',
},
},
};
export const WithHintAndErrorText = Template.bind({});
WithHintAndErrorText.args = {
fields: [
{
name: 'username',
Label: 'Username',
inputType: 'text',
validation: { required: true, minLength: 3 },
HintText: 'Choose a unique username',
ErrorText: 'Username must be at least 3 characters long',
},
{
name: 'email',
Label: 'Email',
inputType: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
HintText: "We'll never share your email",
ErrorText: 'Please enter a valid email address',
},
],
onSubmit: (data) => console.log(data),
};
export const WithInputAdornments = Template.bind({});
WithInputAdornments.args = {
fields: [
{
name: 'username',
Label: 'Username',
inputType: 'text',
InputAdornmentLeft: '@',
},
{
name: 'price',
Label: 'Price',
inputType: 'number',
InputAdornmentLeft: '$',
InputAdornmentRight: '.00',
},
],
onSubmit: (data) => console.log(data),
};
export const WithDefaultValues = Template.bind({});
WithDefaultValues.args = {
fields: [
{
name: 'name',
label: 'Name',
type: 'text',
defaultValue: 'John Doe',
},
{
name: 'email',
label: 'Email',
type: 'email',
defaultValue: 'john@example.com',
},
{
name: 'subscribe',
label: 'Subscribe to newsletter',
type: 'checkbox',
defaultValue: true,
},
{
name: 'preference',
label: 'Preference',
type: 'select',
options: [
{ label: 'Option A', value: 'A' },
{ label: 'Option B', value: 'B' },
{ label: 'Option C', value: 'C' },
],
defaultValue: 'B',
},
],
onSubmit: (data) => console.log(data),
};
export const CustomSubmitButton = Template.bind({});
CustomSubmitButton.args = {
...Default.args,
submitButton: {
text: 'Send Form',
variant: 'primary',
size: 'large',
},
};
export const WithCustomValidation = Template.bind({});
WithCustomValidation.args = {
fields: [
{
name: 'password',
label: 'Password',
type: 'password',
validation: {
required: true,
validate: (value) => {
if (value.length < 8)
return 'Password must be at least 8 characters';
if (!/\d/.test(value))
return 'Password must contain a number';
if (!/[A-Z]/.test(value))
return 'Password must contain an uppercase letter';
return true;
}
},
},
{
name: 'confirmPassword',
label: 'Confirm Password',
type: 'password',
validation: {
required: true,
validate: (value, formValues) => value === formValues.password || 'Passwords do not match',
},
},
],
onSubmit: (data) => console.log(data),
};
export const WithDatePicker = Template.bind({});
WithDatePicker.args = {
fields: [
{
name: 'birthDate',
label: 'Date of Birth',
type: 'date',
validation: {
required: true,
validate: (value) => {
const date = new Date(value);
const now = new Date();
return date < now || 'Date of birth cannot be in the future';
}
},
},
],
onSubmit: (data) => console.log(data),
};
export const WithTextarea = Template.bind({});
WithTextarea.args = {
fields: [
{
name: 'shortBio',
label: 'Short Bio',
type: 'textarea',
validation: { required: true, maxLength: 200 },
placeholder: 'Write a short bio (max 200 characters)',
},
{
name: 'longDescription',
label: 'Detailed Description',
type: 'textarea',
validation: { maxLength: 1000 },
placeholder: 'Provide more details (optional, max 1000 characters)',
},
],
onSubmit: (data) => console.log(data),
};
export const AllInputTypes = Template.bind({});
AllInputTypes.args = {
fields: [
// Text input
{
name: 'name',
label: 'Name',
type: 'text',
validation: { required: true },
placeholder: 'Enter your name',
},
// Number input
{
name: 'age',
label: 'Age',
type: 'number',
validation: { required: true, min: 18, max: 100 },
placeholder: 'Enter your age',
},
// Email input
{
name: 'email',
label: 'Email',
type: 'email',
validation: { required: true, pattern: /^\S+@\S+$/i },
placeholder: 'Enter your email',
},
// Password input
{
name: 'password',
label: 'Password',
type: 'password',
validation: { required: true, minLength: 8 },
placeholder: 'Enter a password',
},
// Textarea
{
name: 'bio',
label: 'Biography',
type: 'textarea',
validation: { required: true, maxLength: 500 },
placeholder: 'Tell us about yourself',
},
// Checkbox
{
name: 'terms',
label: 'I agree to the terms and conditions',
type: 'checkbox',
validation: { required: true },
},
// Radio group
{
name: 'gender',
label: 'Gender',
type: 'radio',
options: [
{ label: 'Male', value: 'male' },
{ label: 'Female', value: 'female' },
{ label: 'Other', value: 'other' },
],
validation: { required: true },
},
// // Select dropdown
{
name: 'country',
label: 'Country',
type: 'select',
options: [
{ label: 'United States', value: 'us' },
{ label: 'Canada', value: 'ca' },
{ label: 'United Kingdom', value: 'uk' },
],
validation: { required: true },
},
// Date picker
{
name: 'birthDate',
label: 'Date of Birth',
type: 'date',
validation: {
required: true,
validate: (value) => {
const date = new Date(value);
const now = new Date();
return date < now || 'Date of birth cannot be in the future';
}
},
},
// Toggle
// Checkbox group
{
name: 'interests',
label: 'Interests',
type: 'checkboxGroup',
options: [
{ label: 'Sports', value: 'sports' },
{ label: 'Music', value: 'music' },
{ label: 'Reading', value: 'reading' },
],
},
],
submitButton: {
text: 'Submit Form',
variant: 'primary',
size: 'large',
},
onSubmit: (data) => console.log(data),
};
//# sourceMappingURL=FormBuilder.stories.js.map