itc-form
v1.0.1
Published
A flexible, schema-driven dynamic form component for Vue 3 + Quasar with validation, field types, and custom rendering support
Maintainers
Readme
ITC Dynamic Form Package
A schema-based reusable form system for Vue 3 + Quasar applications. Build forms dynamically using simple JSON/JavaScript schemas instead of writing repetitive form code.
Features
- ✅ Schema-Based: Define forms using simple JSON/JavaScript objects
- ✅ Multiple Field Types: text, textarea, number, email, password, url, tel, date, time, select, option, toggle, boolean, richtext, file
- ✅ Validation: Built-in validation with custom rules support (validators in
utilities/validators.js) - ✅ Responsive Layout: Grid-based responsive column layout using Quasar's grid system
- ✅ v-model Support: Two-way data binding with reactive form model
- ✅ Slot System: Custom field rendering via slots for external components
- ✅ Quasar Integration: Built on Quasar components (QInput, QSelect, QDate, QTime, etc.)
- ✅ Rich Text Editor: Built-in rich text editor component for richtext fields
- ✅ Helper Functions: Reusable utilities for form operations
Philosophy
Schema-Based Architecture:
Form Schema (JSON) → DynamicForm (Engine) → Rendered FormInstead of writing separate form components for each use case, define your form structure using a simple schema and let DynamicForm handle the rendering.
Getting Started
Prerequisites
- Node.js 18+ or 20+
- npm or pnpm
- Vue 3.5.25+
- Quasar 2.18.6+
Installation
Install the package:
npm install itc-form # or pnpm add itc-formUse in your project:
<script setup> import { DynamicForm } from 'itc-form' import { taskFormSchema } from './schemas/taskForm' const formData = ref({}) const handleSubmit = (data) => { console.log('Form submitted:', data) } </script> <template> <DynamicForm :schema="taskFormSchema" v-model="formData" @submit="handleSubmit" /> </template>
Usage
Basic Example
// Define your form schema
const myFormSchema = {
title: 'User Registration',
submitText: 'Register',
resetText: 'Reset',
showCard: true,
fields: [
{
name: 'email',
label: 'Email',
type: 'email',
required: true,
placeholder: 'Enter your email',
col: { xs: 12, sm: 6 }
},
{
name: 'password',
label: 'Password',
type: 'password',
required: true,
col: { xs: 12, sm: 6 }
}
]
}<template>
<DynamicForm
:schema="myFormSchema"
v-model="formData"
@submit="handleSubmit"
/>
</template>Field Types Supported
- Text Inputs:
text,email,password,url,tel - Text Area:
textareawith configurable rows - Number:
numberwith min/max/step validation - Date & Time:
datepicker,timepicker (12-hour format by default) - Selection:
selectdropdown,option(chips-based multi-select) - Toggle:
toggle/booleanswitch - Advanced:
richtext(with built-in editor),fileupload (slot-based) - Hidden:
hiddeninput field - Custom: Custom field rendering via slots
Schema Structure
Form Schema
{
title: 'Form Title', // Optional
subtitle: 'Form Subtitle', // Optional
submitText: 'Submit', // Optional, default button text
resetText: 'Reset', // Optional, reset button text
showCard: true, // Optional, wrap in QCard
showActions: true, // Optional, show action buttons
submitDisabled: false, // Optional, disable submit button
fields: [ /* field array */ ] // Required
}Field Schema
{
name: 'fieldName', // Required, unique field identifier
label: 'Field Label', // Required
type: 'text', // Required, field type
required: false, // Optional, validation
placeholder: 'Enter value', // Optional
hint: 'Helper text', // Optional
defaultValue: 'default', // Optional, default value
rules: [ /* validation rules */ ], // Optional, custom rules
col: { xs: 12, sm: 6 }, // Optional, responsive layout
meta: { /* type-specific options */ } // Optional
}Validation
Built-in Validators
The package includes validation utilities in utilities/validators.js:
validateEmail(val, strict)- Email validationvalidateURL(val, strict)- URL validationvalidatePhoneNumber(val)- Phone number validationvalidateOnlyNumberAndDecimal(val)- Number validationvalidateAlphaNumWithHyphenUnderscore(val)- Alphanumeric validationgetTypeValidationRule(type, options)- Get validation rule by type
Usage
import { validateEmail, getTypeValidationRule } from 'itc-form'
// In schema
{
name: 'email',
type: 'email',
required: true,
meta: {
validationOptions: { strict: true } // Use strict email validation
}
}
// Custom validation
{
name: 'customField',
type: 'text',
rules: [
(val) => !!val || 'Field is required',
(val) => val.length > 5 || 'Must be at least 6 characters'
]
}Helper Functions
Helper functions available in utilities/helpers.js:
getDefaultValueForType(type)- Get default value for field typegetDateInputMask(dateMask)- Convert date mask format
import { getDefaultValueForType, getDateInputMask } from 'itc-form'Building
Build for Production
npm run build
# or
pnpm run buildThis will:
- Compile JavaScript
- Bundle Vue components
- Generate both ES Modules (
.js) and CommonJS (.cjs) formats - Output to
dist/directory
Build Output Structure
dist/
├─ itc-form.js # ES Module
├─ itc-form.cjs # CommonJS
└─ itc-form.css # StylesTesting Locally
Option 1: Using npm link
In your package directory:
npm linkIn your test project:
npm link itc-form
Option 2: Using File Path
In your test project's
package.json:{ "dependencies": { "itc-form": "file:../itc-form" } }Install:
npm install
Development Workflow
For active development with auto-rebuild:
npm run devChanges will rebuild automatically. Restart your test project's dev server to pick up changes.
Publishing to npm
Before Publishing
Update
package.json:- Verify
nameis unique on npm - Update
version(follow semver) - Verify
filesarray includes onlydist:{ "files": ["dist"] }
- Verify
Build the package:
npm run buildTest the build locally (see Testing Locally section above)
Publishing Steps
Step 1: Enable 2FA or Create Access Token
Option A: Enable 2FA on npm (Recommended)
- Go to https://www.npmjs.com/settings/itcroja/security
- Enable Two-Factor Authentication (2FA)
- Follow the setup process (use authenticator app like Google Authenticator)
- Once enabled, you can publish with 2FA code
Option B: Create Granular Access Token (Alternative)
Go to https://www.npmjs.com/settings/itcroja/tokens
Click Generate New Token → Granular Access Token
Set permissions:
- Type: Automation
- Packages: Select
itc-formor all packages - Permissions: Read and Write
- Expiration: Set as needed
Copy the token (starts with
npm_)Use token for authentication:
npm config set //registry.npmjs.org/:_authToken YOUR_TOKEN_HERE
Step 2: Login to npm
npm loginIf using 2FA, you'll be prompted for the 2FA code during login.
Step 3: Verify you're logged in
npm whoamiStep 4: Check what will be published
npm pack --dry-runStep 5: Publish
npm publishFor scoped packages:
npm publish --access publicNote: If you have 2FA enabled, you may need to use npm publish --otp=YOUR_2FA_CODE or set up automation token.
- Verify on npm:
Visit
https://www.npmjs.com/package/itc-form
Version Management
Use npm version commands to bump versions:
# Patch version (1.0.0 → 1.0.1)
npm version patch
# Minor version (1.0.0 → 1.1.0)
npm version minor
# Major version (1.0.0 → 2.0.0)
npm version majorThen publish:
npm publishConfiguration
External Dependencies
By default, vue and quasar are marked as external (not bundled). The package expects these to be provided by the consuming application.
Quasar Components Required
Ensure these Quasar components are registered in your Quasar config:
// quasar.config.js
framework: {
components: [
'QCard',
'QCardSection',
'QCardActions',
'QInput',
'QSelect',
'QToggle',
'QBtn',
'QForm',
'QDate',
'QTime',
'QFile',
'QPopupProxy',
'QIcon',
'QEditor',
'QColor',
'QTooltip',
'QMenu',
'QList',
'QItem',
'QItemSection',
'QBtnDropdown',
'QSeparator'
]
}Type Definitions
Full TypeScript type definitions available in types/formSchema.ts:
FormSchema- Form configuration interfaceFormField- Field configuration interfaceFormFieldMeta- Field-specific optionsFormFieldCol- Grid layout configuration
Examples
See src/examples/ directory for complete schema examples:
taskFormSchema.js- Task form example with all field typessimpleFormSchema.js- Basic form example
Example: Task Form
import { taskFormSchema } from 'itc-form/src/examples/taskFormSchema'
// Use in component
<DynamicForm
:schema="taskFormSchema"
v-model="formData"
@submit="handleSubmit"
/>Best Practices
- ✅ Use peer dependencies for Vue and Quasar (provided by consumer)
- ✅ Define schemas separately from components for reusability
- ✅ Use validation rules for field-level validation
- ✅ Leverage slots for custom field rendering when needed
- ✅ Use responsive columns (
colprop) for better mobile experience - ✅ Set appropriate default values for better UX
- ❌ Don't bundle Vue or Quasar into the package
- ❌ Don't hard-code form structures - use schemas
Troubleshooting
Component Not Found Errors
- "Failed to resolve component: q-input": Register Quasar components in
quasar.config.js - "Failed to resolve directive: close-popup": Ensure Quasar directives are registered
Build Errors
- "Rollup failed to resolve import": Add the package to
externalinvite.config.ts - "Cannot find module": Ensure package is built (
npm run build)
Import Errors in Test Project
- Ensure the package is built (
npm run build) - Check
package.jsonexports are correct - Verify the import path matches your exports
- Clear node_modules and reinstall
Form Not Showing
- Verify schema structure is correct
- Check that
fieldsarray is not empty - Ensure
v-modelis properly bound - Check browser console for errors
License
MIT
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Build and test locally
- Submit a pull request
Happy coding! 🚀
