JSPM

  • Created
  • Published
  • Downloads 170
  • Score
    100M100P100Q94262F
  • License MIT

Collaboration form elements

Package Exports

  • hazo_collab_forms
  • hazo_collab_forms/components
  • hazo_collab_forms/lib
  • hazo_collab_forms/utils

Readme

Hazo Collab Forms

npm version License: MIT

React form components with integrated chat collaboration, built for Next.js with TypeScript and Tailwind CSS.

Features

  • Integrated Chat Collaboration: Each form field supports real-time chat discussions
  • Advanced Field Controls: Visibility toggle, lock/unlock, field duplication, and soft delete
  • Role-Based UI: Author and responder roles for granular control over field interactions
  • File Upload with Validation: Built-in file upload with custom validation callbacks
  • Mandatory File Indicator: Visual indicators (red asterisk) for required file uploads
  • Custom File Validators: Implement custom validation logic before file upload
  • Form Sets: JSON-based dynamic form generation with full file upload support
  • Type-Safe: Written in TypeScript with comprehensive type definitions
  • Tailwind CSS Styling: Fully customizable with Tailwind CSS classes
  • shadcn/ui Components: Built on top of accessible Radix UI primitives

Installation

Step 1: Install the Package

npm install hazo_collab_forms

Step 2: Install Peer Dependencies

# Core React dependencies (skip if already installed)
npm install react react-dom

# UI dependencies
npm install react-icons sonner lucide-react
npm install @radix-ui/react-dialog @radix-ui/react-label

# Hazo ecosystem packages (required for chat functionality)
npm install hazo_chat hazo_ui hazo_auth hazo_config

Step 3: Install shadcn/ui Components

This package requires shadcn/ui components. If you haven't initialized shadcn/ui yet:

npx shadcn@latest init

Then install the required components:

# Core components (required for all form fields)
npx shadcn@latest add button label dialog tooltip sonner

# For HazoCollabFormCombo (dropdown/select)
npx shadcn@latest add popover command

# For HazoCollabFormDate (date picker)
npx shadcn@latest add calendar

# For file upload functionality (required when using accept_files prop)
npx shadcn@latest add accordion

# Optional but recommended
npx shadcn@latest add separator card

Step 4: Configure Next.js

Add to your next.config.js:

const nextConfig = {
  transpilePackages: ['hazo_collab_forms'],
};
module.exports = nextConfig;

Step 5: Configure Tailwind CSS

Add to tailwind.config.ts content array:

content: [
  // ... your existing paths
  "./node_modules/hazo_collab_forms/**/*.{js,ts,jsx,tsx}",
],

Step 6: Create Config Files

Copy the template config files to your project root:

cp node_modules/hazo_collab_forms/templates/*.ini ./

This creates:

  • hazo_collab_forms_config.ini - Main package config
  • hazo_chat_config.ini - Chat functionality config
  • hazo_auth_config.ini - Authentication config

Step 7: Verify Installation

npx hazo-collab-forms-verify

This checks all dependencies, config files, and shadcn components are properly installed.


Quick Reference

One-Line Install (All Dependencies)

npm install hazo_collab_forms react react-dom react-icons sonner lucide-react \
  @radix-ui/react-dialog @radix-ui/react-label hazo_chat hazo_ui hazo_auth hazo_config

One-Line shadcn Install (All Components)

npx shadcn@latest add button label dialog tooltip sonner popover command calendar accordion separator card

Usage

Basic Example

'use client';

import { HazoCollabFormInputbox } from 'hazo_collab_forms';
import { useState } from 'react';

export default function MyForm() {
  const [value, setValue] = useState('');

  return (
    <HazoCollabFormInputbox
      label="Your Name"
      value={value}
      onChange={setValue}
      field_data_id="user-name"
      field_name="User Name"
      hazo_chat_receiver_user_id="recipient-user-id"
    />
  );
}

File Upload with Validation

'use client';

import { HazoCollabFormInputbox } from 'hazo_collab_forms';
import { useState } from 'react';

export default function DocumentUpload() {
  const [value, setValue] = useState('');

  return (
    <HazoCollabFormInputbox
      label="Invoice Upload"
      value={value}
      onChange={setValue}
      accept_files={true}
      files_dir="public/uploads"
      min_files={1}  // Shows red asterisk (mandatory indicator)
      max_files={5}
      file_accept=".pdf"
      file_validator={(file) => {
        // Custom validation - filename pattern check
        if (!file.name.match(/^INV-\d{4}\.pdf$/i)) {
          return 'File name must match pattern: INV-0000.pdf';
        }
        // Size check (5MB limit)
        if (file.size > 5 * 1024 * 1024) {
          return 'File size must be under 5MB';
        }
        return null; // Accept file
      }}
    />
  );
}

Advanced Field Control Icons

The package exports standalone control icons for building custom form workflows:

'use client';

import {
  HazoCollabFormInputbox,
  CollabFormVisibilityIcon,
  CollabFormLockIcon,
  CollabFormAddEntryIcon,
  CollabFormDeleteEntryIcon,
  CollabFormDeleteFieldIcon,
} from 'hazo_collab_forms';
import { useState } from 'react';

export default function AdvancedForm() {
  const [value, setValue] = useState('');
  const [visibility, setVisibility] = useState<'visible' | 'hidden'>('visible');
  const [locked, setLocked] = useState(false);

  return (
    <div>
      {/* Visibility Toggle - author role only */}
      <CollabFormVisibilityIcon
        label="Company Name"
        visibility={visibility}
        on_visibility_change={setVisibility}
        user_role="author"
      />

      {/* Lock/Unlock Field - author role only */}
      <CollabFormLockIcon
        label="Company Name"
        locked={locked}
        on_lock_change={setLocked}
        user_role="author"
      />

      {/* Add Entry - duplicate field */}
      <CollabFormAddEntryIcon
        label="Contact Person"
        field_id="contact_person"
        on_add_entry={(field_id) => console.log('Add entry:', field_id)}
      />

      {/* Delete Entry - remove duplicated field */}
      <CollabFormDeleteEntryIcon
        label="Contact Person"
        field_id="contact_person_2"
        on_delete_entry={(field_id) => console.log('Delete entry:', field_id)}
      />

      {/* Delete Field - soft delete - author role only */}
      <CollabFormDeleteFieldIcon
        label="Optional Field"
        field_id="optional_field"
        on_delete={(field_id) => console.log('Delete field:', field_id)}
        user_role="author"
      />
    </div>
  );
}

Icon Components:

Icon Component Description User Role Restriction
CollabFormVisibilityIcon Toggle field visibility (show/hide) Author only
CollabFormLockIcon Toggle field lock (read-only mode) Author only
CollabFormAddEntryIcon Duplicate a field entry None
CollabFormDeleteEntryIcon Remove a duplicated entry None
CollabFormDeleteFieldIcon Soft delete a field Author only

Role-Based Rendering:

  • Icons marked "Author only" render only when user_role="author" is passed
  • Default user_role is "responder", which hides author-only controls
  • This allows the same component to behave differently for form authors vs. responders

Field-Level Controls in HazoCollabFormSet

When using HazoCollabFormSet with JSON-based field definitions, you can configure lock, visibility, and delete controls at the field level. This allows different fields to have different controls.

Cascade Priority:

  1. Field-level FieldConfig properties → overrides form-level defaults
  2. Form-level HazoCollabFormSetProps → applies to all fields
  3. Hardcoded fallback → false (disabled)
'use client';

import { HazoCollabFormSet, FieldConfig } from 'hazo_collab_forms';

const fields: FieldConfig[] = [
  {
    id: "customer_name",
    label: "Customer Name",
    field_type: "field",
    component_type: "HazoCollabFormInputbox",
    value: "",
    // Uses form-level defaults
  },
  {
    id: "tax_file_number",
    label: "Tax File Number",
    field_type: "field",
    component_type: "HazoCollabFormInputbox",
    value: "",
    enable_lock: true,
    enable_visibility_toggle: true,  // Field-level override
    enable_delete: false
  },
  {
    id: "internal_notes",
    label: "Internal Notes",
    field_type: "field",
    component_type: "HazoCollabFormTextArea",
    value: "",
    enable_lock: false,              // Hide lock on this field
    enable_visibility_toggle: true,
    enable_delete: true              // Show delete on this field
  }
];

export default function CustomerForm() {
  return (
    <HazoCollabFormSet
      fields_set={{ name: "Customer Form", fields }}
      user_role="author"
      enable_lock={true}              // Default for all fields
      enable_visibility_toggle={false} // Default for all fields
      enable_delete={false}            // Default for all fields
    />
  );
}

Available FieldConfig Control Properties:

  • enable_lock?: boolean - Show lock icon
  • enable_visibility_toggle?: boolean - Show visibility toggle icon
  • enable_delete?: boolean - Show delete icon
  • locked?: boolean - Initial lock state
  • visibility?: 'visible' | 'hidden' - Initial visibility state

Components

Component Description Required shadcn
HazoCollabFormInputbox Text input with validation button, label, dialog
HazoCollabFormTextArea Multi-line text input button, label, dialog
HazoCollabFormCheckbox Boolean toggle button, label, dialog
HazoCollabFormCombo Dropdown select with search + popover, command
HazoCollabFormRadio Radio button group button, label, dialog
HazoCollabFormDate Date or date-range picker + calendar
HazoCollabFormGroup Field grouping container button, label, dialog
HazoCollabFormSet Complete form with field arrays all components
File Upload When using accept_files prop + accordion (required)

Import Paths

// Default: All client-safe components and utilities
import { HazoCollabFormInputbox, cn } from 'hazo_collab_forms';

// Components only
import { HazoCollabFormInputbox } from 'hazo_collab_forms/components';

// Utilities only
import { cn, use_collab_chat } from 'hazo_collab_forms/utils';

// Server-only (config functions)
import { get_config } from 'hazo_collab_forms/lib';

Troubleshooting

lucide-react Version Conflicts

Different Hazo packages require different versions of lucide-react. Add this to your package.json:

"overrides": {
  "lucide-react": "^0.553.0"
}

Missing shadcn Components

If you see errors about missing components, install the specific shadcn component:

npx shadcn@latest add [component-name]

Important: If you're using file upload functionality (accept_files prop on any form field), you must install the accordion component:

npx shadcn@latest add accordion

Verify Your Setup

Run the verification tool to check for common issues:

npx hazo-collab-forms-verify

See SETUP_CHECKLIST.md for detailed troubleshooting.


Development

Package Structure

  • Root: ES module npm package
  • test-app: Next.js application for testing

Commands

npm run build          # Build the package
npm run dev:package    # Watch mode for development
npm run dev:test-app   # Build and run test app
npm run build:test-app # Build for production
npm run clean          # Remove dist directory

TypeScript Configuration

  • tsconfig.json: Development (bundler module resolution)
  • tsconfig.build.json: Build (Node16 for ES module output)

ES Module Exports

All exports use explicit .js extensions as required for ES modules:

export * from './lib/index.js';
export * from './components/index.js';

License

MIT