npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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

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 Form

Instead 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

  1. Install the package:

    npm install itc-form
    # or
    pnpm add itc-form
  2. Use 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: textarea with configurable rows
  • Number: number with min/max/step validation
  • Date & Time: date picker, time picker (12-hour format by default)
  • Selection: select dropdown, option (chips-based multi-select)
  • Toggle: toggle / boolean switch
  • Advanced: richtext (with built-in editor), file upload (slot-based)
  • Hidden: hidden input 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 validation
  • validateURL(val, strict) - URL validation
  • validatePhoneNumber(val) - Phone number validation
  • validateOnlyNumberAndDecimal(val) - Number validation
  • validateAlphaNumWithHyphenUnderscore(val) - Alphanumeric validation
  • getTypeValidationRule(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 type
  • getDateInputMask(dateMask) - Convert date mask format
import { getDefaultValueForType, getDateInputMask } from 'itc-form'

Building

Build for Production

npm run build
# or
pnpm run build

This 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     # Styles

Testing Locally

Option 1: Using npm link

  1. In your package directory:

    npm link
  2. In your test project:

    npm link itc-form

Option 2: Using File Path

  1. In your test project's package.json:

    {
      "dependencies": {
        "itc-form": "file:../itc-form"
      }
    }
  2. Install:

    npm install

Development Workflow

For active development with auto-rebuild:

npm run dev

Changes will rebuild automatically. Restart your test project's dev server to pick up changes.

Publishing to npm

Before Publishing

  1. Update package.json:

    • Verify name is unique on npm
    • Update version (follow semver)
    • Verify files array includes only dist:
      {
        "files": ["dist"]
      }
  2. Build the package:

    npm run build
  3. Test 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)

  1. Go to https://www.npmjs.com/settings/itcroja/security
  2. Enable Two-Factor Authentication (2FA)
  3. Follow the setup process (use authenticator app like Google Authenticator)
  4. Once enabled, you can publish with 2FA code

Option B: Create Granular Access Token (Alternative)

  1. Go to https://www.npmjs.com/settings/itcroja/tokens

  2. Click Generate New TokenGranular Access Token

  3. Set permissions:

    • Type: Automation
    • Packages: Select itc-form or all packages
    • Permissions: Read and Write
    • Expiration: Set as needed
  4. Copy the token (starts with npm_)

  5. Use token for authentication:

    npm config set //registry.npmjs.org/:_authToken YOUR_TOKEN_HERE

Step 2: Login to npm

npm login

If using 2FA, you'll be prompted for the 2FA code during login.

Step 3: Verify you're logged in

npm whoami

Step 4: Check what will be published

npm pack --dry-run

Step 5: Publish

npm publish

For scoped packages:

npm publish --access public

Note: If you have 2FA enabled, you may need to use npm publish --otp=YOUR_2FA_CODE or set up automation token.

  1. 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 major

Then publish:

npm publish

Configuration

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 interface
  • FormField - Field configuration interface
  • FormFieldMeta - Field-specific options
  • FormFieldCol - Grid layout configuration

Examples

See src/examples/ directory for complete schema examples:

  • taskFormSchema.js - Task form example with all field types
  • simpleFormSchema.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 (col prop) 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 external in vite.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.json exports are correct
  • Verify the import path matches your exports
  • Clear node_modules and reinstall

Form Not Showing

  • Verify schema structure is correct
  • Check that fields array is not empty
  • Ensure v-model is properly bound
  • Check browser console for errors

License

MIT

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Build and test locally
  5. Submit a pull request

Happy coding! 🚀