UNPKG

begin-widgets

Version:

Easily embed powerful workflow building and running capabilities into your web applications with Lit-based web components. Includes HTML export for server-side PDF generation.

1,120 lines (900 loc) • 42.8 kB
# ✨ Begin Widgets ✨ Easily embed powerful workflow building and running capabilities into your web applications! Begin Widgets provides Lit-based web components that let you: - Visually **build workflow templates** with custom forms and steps. - **Run instances** of those workflows, guiding users through steps. - Integrate seamlessly into your existing application with a simple JavaScript API. Perfect for onboarding flows, request processes, checklists, approvals, and any task requiring structured, sequential steps. ## Installation ### From npm (Recommended) ```bash npm install begin-widgets ``` ### From CDN ```html <script src="https://unpkg.com/begin-widgets/dist/begin-widgets.umd.js"></script> ``` --- ## Key Features & Benefits - **šŸš€ Rapid Integration:** Embed complex workflow UIs with just a few lines of JavaScript using `createBuilder` and `createRunner`. - **🧩 Focused Builder (`builder-widget`):** - Clean, intuitive interface to create workflow templates with steps and form elements - Drag-and-drop step reordering for easy workflow organization - Step-by-step template creation with title, description, and elements - Modern UI design with proper form validation and user feedback - Support for multiple question types and content elements - **šŸƒā€ā™‚ļø Smooth Runner (`runner-widget`):** - Self-contained: Runs entirely from a single `Instance` object snapshot - Multiple execution modes: Default, Preview, Admin, View-Only, and Print modes for different use cases - Guides users step-by-step with clear progress indication - Includes comprehensive validation for required fields - Provides clear event hooks (`onInstanceUpdated`, `onSignatureCaptured`, `onFileUploaded`) for saving progress and final results - Responsive design that adapts to different screen sizes - **šŸ—ļø Modern Web Components:** Built with [Lit](https://lit.dev/) for encapsulated, reusable, and framework-agnostic components. - **šŸ”’ Consistent Runs:** Instances are snapshots of the workflow at creation time, ensuring that changes to the main workflow template don't break in-progress tasks. - **šŸ”Œ Event-Driven:** Easily hook into the workflow lifecycle using callbacks to save data to your backend, trigger notifications, or update your UI. ## Core Concepts - **Workflow:** The reusable blueprint or template for a process, containing steps and elements (form questions and content blocks). - **Instance:** A specific, runnable execution of a Workflow, captured as a snapshot. It includes the exact steps/elements from the Workflow at the time of creation, plus current progress and any instance-specific details. - **Builder:** The component (`<builder-widget>`) used to create `Workflow` templates with a focused, clean interface. - **Runner:** The component (`<runner-widget>`) used to execute an `Instance`, presenting the steps and elements to the user. ## Runner Modes The Runner widget supports different distinct modes for different use cases: ### Default Mode **Purpose:** Standard workflow execution with full functionality. **Configuration:** ```javascript createRunner("runner-container", { instance: instanceData, // Required: Instance object mode: "default", // Optional: Default if not specified // ... other options }); ``` **Features:** - āœ… **Data Persistence:** Form data is automatically saved to localStorage - āœ… **Validation:** Required field validation runs on each step - āœ… **Step Completion Tracking:** Progress is tracked and steps are marked as completed - āœ… **Callbacks:** All callbacks fire (signature capture, file upload, etc.) - āœ… **Smart Navigation:** Next button progresses through assigned steps only - āœ… **Transparent Unassigned Steps:** Clickable sidebar access to view unassigned steps in read-only mode - āœ… **Assignment-Based Interaction:** Full editing for assigned steps, read-only viewing for unassigned steps - āœ… **Next/Submit Buttons:** Visible only when viewing assigned steps **Use Cases:** - Production workflow execution - User onboarding processes - Approval workflows - Collaborative workflows where users need transparency into other steps - Any scenario requiring data persistence, validation, and step-based assignments #### Default Mode: Transparent Unassigned Step Viewing In default mode, users can now click on **any step** in the sidebar for full workflow transparency: **Assigned Steps (Full Mode):** - āœ… **Full interaction:** Edit, validate, save, and progress through workflow - āœ… **Navigation buttons:** Next/Save/Submit buttons are visible - āœ… **Data persistence:** Changes are saved and callbacks fire - šŸŽÆ **Badge shows:** "Assigned" **Unassigned Steps (Read-Only Mode):** - šŸ‘ļø **View-only access:** Can see existing responses and form structure - āŒ **No interaction:** All inputs are disabled and read-only - āŒ **No buttons:** Next/Save/Submit buttons are hidden - āŒ **No data changes:** Cannot modify or save any data - šŸ·ļø **Badge shows:** "Not Assigned" **Next Button Behavior:** - The Next button still progresses through assigned steps only - Clicking unassigned steps is for viewing/transparency only - Users can freely navigate back to their assigned workflow This provides complete workflow transparency while maintaining assignment boundaries and data integrity. ### Preview Mode **Purpose:** Interactive preview of workflow templates without data persistence. **Configuration:** ```javascript createRunner("runner-container", { workflow: workflowData, // Required: Workflow object (not Instance) mode: "preview", // Required: Must be explicitly set // ... other options }); ``` **Features:** - āœ… **Interactive Inputs:** Users can interact with all form elements - āœ… **No Data Saving:** Form data is not persisted (no localStorage usage) - āœ… **No Validation:** Required field validation is disabled - āœ… **Free Navigation:** Users can click any step in the sidebar to navigate freely - āœ… **No Callbacks:** Signature and file upload callbacks are disabled - āœ… **No Navigation Buttons:** Next/Submit buttons are hidden - āœ… **Same Visual Layout:** Identical appearance to default mode **Use Cases:** - Workflow template preview - User experience testing - Stakeholder demonstrations - Template review and approval processes ### Admin Mode **Purpose:** Administrative access for workflow management with unrestricted navigation and step-by-step saving. **Configuration:** ```javascript createRunner("runner-container", { instance: instanceData, // Required: Instance object mode: "admin", // Required: Must be explicitly set currentUser: userData, // Required: User with admin access // ... other options }); ``` **Features:** - āœ… **Unrestricted Navigation:** Access any step regardless of assignment or completion status - āœ… **Step-by-Step Saving:** "Save" button (instead of "Next") allows saving progress without advancing - āœ… **All Callbacks Active:** Signature capture, file upload, and instance update callbacks fire normally - āœ… **Assignment Bypass:** Can view and edit steps not assigned to current user - āœ… **Data Persistence:** Form data is saved to localStorage - āœ… **Post-Submission Access:** Can still navigate and edit after workflow submission - āœ… **Validation Active:** Required field validation still applies **Use Cases:** - Workflow administration and troubleshooting - Helping users complete stuck workflows - Data correction and updates - Workflow testing and QA - Support team assistance ### View-Only Mode **Purpose:** Read-only viewing of completed workflow data with pre-filled responses displayed as non-editable content. **Configuration:** ```javascript createRunner("runner-container", { instance: completedInstanceData, // Required: Instance with responses mode: "view-only", // Required: Must be explicitly set currentUser: userData, // Optional: For display purposes // ... other options }); ``` **Features:** - āœ… **Free Navigation:** Navigate to any step freely (like admin mode) - āœ… **Pre-filled Display:** All form inputs show existing response data - āœ… **All Inputs Disabled:** No editing possible - purely read-only - āœ… **File/Signature Links:** File uploads and signatures display as clickable links - āœ… **No Action Buttons:** No Next/Save/Submit buttons visible - āœ… **No Data Persistence:** No localStorage usage or data saving - āœ… **No Callbacks:** Callbacks are disabled (read-only mode) - āœ… **Post-Submission View:** Perfect for viewing submitted/completed workflows **Use Cases:** - Viewing completed workflow submissions - Audit trails and compliance documentation - Historical workflow data review - Sharing completed forms with stakeholders - Read-only workflow previews for approval ### Print Mode **Purpose:** Print-optimized display of completed workflow data with all steps shown on one continuous page. **Configuration:** ```javascript createRunner("runner-container", { instance: completedInstanceData, // Required: Instance with responses mode: "print", // Required: Must be explicitly set currentUser: userData, // Optional: For display purposes // ... other options }); ``` **Features:** - āœ… **Single Page Layout:** All workflow steps displayed continuously on one page - āœ… **No Sidebar:** Clean layout without step navigation for optimal printing - āœ… **Pre-filled Display:** All form inputs show existing response data - āœ… **All Inputs Disabled:** No editing possible - purely read-only - āœ… **Detailed File Information:** File uploads show filename, size, type, and modification date - āœ… **Print-Optimized Styling:** Special CSS for clean printing with proper page breaks - āœ… **No Action Buttons:** No interactive elements that don't work in print - āœ… **No Data Persistence:** No localStorage usage or data saving - āœ… **No Callbacks:** Callbacks are disabled (read-only mode) **File Display Enhancement:** - **File Info Objects:** Shows detailed metadata (filename, size, type, date) - **URL References:** Extracts filename and type from URLs automatically - **Print-Friendly:** No non-functional buttons or links **Use Cases:** - Generating PDF documents of completed workflows - Physical document printing for records - Compliance documentation requiring paper copies - Executive summaries and reports - Archival purposes ### Mode Comparison | Feature | Default Mode | Preview Mode | Admin Mode | View-Only Mode | Print Mode | | -------------------------- | -------------------------------------------------------- | --------------------- | ---------------------- | -------------------------------- | -------------------------------- | | **Data Source** | Instance object | Workflow object | Instance object | Instance object (with responses) | Instance object (with responses) | | **Data Persistence** | āœ… localStorage | āŒ None | āœ… localStorage | āŒ None | āŒ None | | **Validation** | āœ… Required fields | āŒ Disabled | āœ… Required fields | āŒ N/A (read-only) | āŒ N/A (read-only) | | **Step Navigation** | šŸ”„ Smart (assigned: restricted, unassigned: view-only) | āœ… Free (any step) | āœ… Free (any step) | āœ… Free (any step) | āŒ Single page view | | **Input Editing** | šŸ”„ Conditional (assigned: enabled, unassigned: disabled) | āœ… Enabled | āœ… Enabled | āŒ Disabled (read-only) | āŒ Disabled (read-only) | | **Callbacks** | āœ… All callbacks fire (assigned steps only) | āŒ Callbacks disabled | āœ… All callbacks fire | āŒ Callbacks disabled | āŒ Callbacks disabled | | **Navigation Buttons** | šŸ”„ Conditional (visible for assigned steps only) | āŒ Hidden | āœ… Save button visible | āŒ Hidden | āŒ Hidden | | **Assignment Checks** | āœ… Enforced | āŒ Bypassed | āŒ Bypassed | āŒ Bypassed | āŒ Bypassed | | **Post-Submission Access** | āŒ Blocked | āœ… Always available | āœ… Always available | āœ… Always available | āœ… Always available | | **File/Signature Display** | Form inputs | Form inputs | Form inputs | šŸ”— Clickable links | šŸ“„ Detailed info display | | **Layout** | Sidebar + single step | Sidebar + single step | Sidebar + single step | Sidebar + single step | šŸ“„ All steps on one page | | **Primary Use Case** | Production execution | Template preview | Admin management | Completed data viewing | Document printing | ## Supported Elements ### Question Elements (Form Inputs) | Type | Description | Features | | ------------- | ---------------------- | ------------------------------------------------------ | | `text_input` | Single-line text input | Placeholder text, validation | | `textarea` | Multi-line text area | Resizable, placeholder text | | `select` | Dropdown selection | Multiple options, placeholder | | `number` | Numeric input | Number validation | | `radio` | Radio button group | Multiple options, single selection | | `checkbox` | Checkbox input | Single checkbox or checkbox group | | `date` | Date picker | Date validation | | `file_upload` | File upload | File selection, 5MB limit, client callback | | `signature` | Digital signature pad | SVG output, responsive canvas, callback on next/submit | ### Content Elements (Display Only) | Type | Description | Features | | ---------- | ------------------ | -------------------------- | | `text` | Plain text content | Simple text display | | `markdown` | Markdown content | Headers, lists, formatting | | `html` | HTML content | Custom HTML rendering | | `divider` | Visual separator | Optional caption | | `image` | Image display | URL, alt text, caption | | `video` | Video display | URL, caption | | `file` | File display | URL, caption | ### Features - **Validation:** Required field validation for all question types - **Responsive Design:** All elements adapt to different screen sizes - **Accessibility:** Proper ARIA labels and keyboard navigation - **Type Safety:** Full TypeScript support for all element types - **Digital Signatures:** Responsive signature pad with SVG output and data URL generation. Signature callbacks are triggered when users click "Next" or "Submit" to capture the final signature data. - **Multiple Signatures:** Support for multiple signature elements on the same form - **File Uploads:** File selection with 5MB limit. File upload callbacks are triggered immediately when a file is selected. - **Progress Tracking:** Real-time progress updates and completion tracking ## Getting Started ### Prerequisites - Node.js (v18+ recommended) - npm ### Installation & Setup 1. **Clone:** `git clone <your-repo-url> && cd begin-widgets` 2. **Install:** `npm install` ## Development Workflow This project supports two distinct modes for different use cases: ### šŸ”§ Development Mode For active development with hot reload and fast iteration: ```bash npm run dev ``` - **URL:** http://localhost:5173/ - **Features:** Hot module replacement, TypeScript compilation, ES modules - **Use case:** Active development, debugging, adding features - **How it works:** Vite serves source files directly using ES modules ### šŸš€ Production Preview Mode For testing the built library as it would be distributed: ```bash npm run build npm run preview ``` - **URL:** http://localhost:4173/ - **Features:** Optimized UMD bundle, production-ready assets - **Use case:** Testing final builds, integration testing, demo purposes - **How it works:** Creates a UMD bundle and serves the optimized HTML ### Key Differences | Aspect | Development (`npm run dev`) | Production (`npm run preview`) | | ------------- | --------------------------- | ------------------------------ | | **Loading** | ES modules from `/src/` | UMD bundle from `/dist/` | | **Speed** | Fast startup, HMR | Slower startup, no HMR | | **Files** | Source TypeScript files | Compiled JavaScript bundle | | **Debugging** | Source maps, readable code | Minified bundle | | **Use Cases** | Development, debugging | Final testing, demos | ### Demo Features Both modes include a demo with: - **Builder Tab:** Create workflow templates with steps and form elements (questions, content, etc.) using an intuitive interface - **Runner Tab:** Execute workflow instances with step-by-step progression - **Sample Data:** Pre-loaded workflows and instances for testing ### Build Process Details The build process includes a custom script that: 1. **TypeScript Compilation:** `tsc` compiles source files 2. **Bundle Creation:** `vite build` creates the UMD bundle 3. **HTML Processing:** `scripts/build-html.js` converts the HTML to use the UMD bundle ## Quick Usage Example ### From npm (Recommended) ```bash npm install begin-widgets ``` ```typescript import { createBuilder, createRunner } from "begin-widgets"; // Initialize Builder createBuilder("workflow-builder", { onSave: (workflowData) => { console.log("New workflow template created:", workflowData); // Save the workflow template to your backend saveWorkflowTemplate(workflowData); }, onCancel: () => { console.log("Template creation cancelled"); // Handle cancellation (e.g., redirect to workflows list) }, }); // Initialize Runner (Default Mode) const instanceData = await fetchInstanceFromBackend("instance-id-123"); if (instanceData && instanceData.steps) { createRunner("workflow-runner", { instance: instanceData, mode: "default", // Optional: Default if not specified onInstanceUpdated: (detail) => { console.log("Progress Update:", detail); // Save progress data (for both step updates and final submission) saveInstanceProgress(detail.instanceId, detail); // Check if this is the final submission (no current step) if (!detail.currentStep) { console.log("Workflow Complete!"); } }, onSignatureCaptured: (detail) => { console.log("Signature captured:", detail.questionId); console.log("Instance ID:", detail.instanceId); console.log("Step ID:", detail.stepId); console.log("SVG Data:", detail.svgData); console.log("Data URL:", detail.dataURL); // Save signature data to your backend // Note: This callback is triggered when user clicks "Next" or "Submit" saveSignatureData( detail.instanceId, detail.questionId, detail.svgData, detail.dataURL ); }, onFileUploaded: (detail) => { console.log("File uploaded:", detail.questionId); console.log("Instance ID:", detail.instanceId); console.log("Step ID:", detail.stepId); console.log("File name:", detail.fileName); console.log("File size:", detail.fileSize); console.log("File type:", detail.fileType); console.log("File object:", detail.file); // Handle file upload to your backend/storage // Note: This callback is triggered immediately when a file is selected handleFileUpload(detail.instanceId, detail.questionId, detail.file); }, }); } // Initialize Runner (Preview Mode) const workflowData = await fetchWorkflowFromBackend("workflow-id-456"); if (workflowData && workflowData.steps) { createRunner("workflow-preview", { workflow: workflowData, // Note: workflow, not instance mode: "preview", // Required for preview mode onSignatureCaptured: (detail) => { console.log("Preview: Signature captured:", detail.questionId); console.log("Preview: Instance ID:", detail.instanceId); console.log("Preview: Step ID:", detail.stepId); // Callbacks are disabled in preview mode, but still available for logging }, onFileUploaded: (detail) => { console.log("Preview: File uploaded:", detail.questionId); console.log("Preview: Instance ID:", detail.instanceId); console.log("Preview: Step ID:", detail.stepId); console.log("Preview: File name:", detail.fileName); // Callbacks are disabled in preview mode, but still available for logging }, }); } ``` ### From CDN (UMD Bundle) 1. **Include Script:** ```html <script src="https://unpkg.com/begin-widgets/dist/begin-widgets.umd.js"></script> ``` 2. **Add Mount Points:** ```html <div id="workflow-builder"></div> <div id="workflow-runner"></div> ``` 3. **Initialize with JavaScript:** ```javascript document.addEventListener('DOMContentLoaded', () => { // --- Initialize Builder --- if (Begin.createBuilder) { Begin.createBuilder('workflow-builder', { // Callback when a workflow template is saved onSave: (workflowData) => { console.log('New workflow template created:', workflowData); // Save the workflow template to your backend saveWorkflowTemplate(workflowData); }, onCancel: () => { console.log('Template creation cancelled'); // Handle cancellation (e.g., redirect to workflows list) } }); } // --- Initialize Runner (Default Mode) --- if (Begin.createRunner) { // Fetch a specific instance object from your backend. // This instance object MUST contain the 'steps' array. const instanceData = await fetchInstanceFromBackend('instance-id-123'); if (instanceData && instanceData.steps) { Begin.createRunner('workflow-runner', { instance: instanceData, mode: 'default', // Optional: Default if not specified onInstanceUpdated: (detail) => { console.log('Progress Update:', detail); // Save progress data (for both step updates and final submission) saveInstanceProgress(detail.instanceId, detail); // Check if this is the final submission (no current step) if (!detail.currentStep) { console.log('Workflow Complete!'); } }, onSignatureCaptured: (detail) => { console.log('Signature captured:', detail.questionId); console.log('Instance ID:', detail.instanceId); console.log('Step ID:', detail.stepId); console.log('SVG Data:', detail.svgData); console.log('Data URL:', detail.dataURL); // Save signature data to your backend // Note: This callback is triggered when user clicks "Next" or "Submit" saveSignatureData(detail.instanceId, detail.questionId, detail.svgData, detail.dataURL); }, onFileUploaded: (detail) => { console.log('File uploaded:', detail.questionId); console.log('Instance ID:', detail.instanceId); console.log('Step ID:', detail.stepId); console.log('File name:', detail.fileName); console.log('File size:', detail.fileSize); console.log('File type:', detail.fileType); // Handle file upload to your backend/storage // Note: This callback is triggered immediately when a file is selected handleFileUpload(detail.instanceId, detail.questionId, detail.file); } }); } else { console.error("Failed to load instance or instance missing steps."); } } // --- Initialize Runner (Preview Mode) --- if (Begin.createRunner) { // Fetch a workflow template from your backend for preview. // This workflow object MUST contain the 'steps' array. const workflowData = await fetchWorkflowFromBackend('workflow-id-456'); if (workflowData && workflowData.steps) { Begin.createRunner('workflow-preview', { workflow: workflowData, // Note: workflow, not instance mode: 'preview', // Required for preview mode onSignatureCaptured: (detail) => { console.log('Preview: Signature captured:', detail.questionId); console.log('Preview: Instance ID:', detail.instanceId); console.log('Preview: Step ID:', detail.stepId); // Callbacks are disabled in preview mode, but still available for logging }, onFileUploaded: (detail) => { console.log('Preview: File uploaded:', detail.questionId); console.log('Preview: Instance ID:', detail.instanceId); console.log('Preview: Step ID:', detail.stepId); console.log('Preview: File name:', detail.fileName); // Callbacks are disabled in preview mode, but still available for logging } }); } else { console.error("Failed to load workflow or workflow missing steps."); } } }); ``` ### For ES Module Projects If you're integrating into a modern build system that supports ES modules: ```javascript import { createBuilder, createRunner } from "./src/lib.ts"; // Use createBuilder and createRunner directly createBuilder("builder-container", { onSave: (workflowData) => console.log("Template saved:", workflowData), onCancel: () => console.log("Template creation cancelled"), }); // Default mode (production execution) createRunner("runner-container", { instance: instanceData, mode: "default", // Optional: Default if not specified onInstanceUpdated: (detail) => { console.log("Progress:", detail); if (!detail.currentStep) console.log("Complete!"); }, onSignatureCaptured: (detail) => console.log( "Signature:", detail.questionId, "Step:", detail.stepId, "Instance:", detail.instanceId ), onFileUploaded: (detail) => console.log( "File:", detail.fileName, "Step:", detail.stepId, "Instance:", detail.instanceId ), }); // Preview mode (template preview) createRunner("preview-container", { workflow: workflowData, // Note: workflow, not instance mode: "preview", // Required for preview mode onSignatureCaptured: (detail) => console.log( "Preview Signature:", detail.questionId, "Step:", detail.stepId ), onFileUploaded: (detail) => console.log("Preview File:", detail.fileName, "Step:", detail.stepId), }); // Admin mode (administrative access) createRunner("admin-container", { instance: instanceData, // Instance object with current state mode: "admin", // Required for admin mode currentUser: adminUserData, // Admin user credentials onInstanceUpdated: (detail) => { console.log("Admin: Progress updated:", detail); // Save admin changes to backend saveAdminChanges(detail.instanceId, detail); }, onSignatureCaptured: (detail) => console.log("Admin Signature:", detail.questionId, "Step:", detail.stepId), onFileUploaded: (detail) => console.log("Admin File:", detail.fileName, "Step:", detail.stepId), }); // View-only mode (read-only viewing of completed data) createRunner("view-only-container", { instance: completedInstanceData, // Instance with filled responses mode: "view-only", // Required for view-only mode currentUser: viewerUserData, // Optional: For display purposes // Note: Callbacks are disabled in view-only mode // Files and signatures display as clickable links instead of form inputs }); // Print mode (print-optimized display of all steps on one page) createRunner("print-container", { instance: completedInstanceData, // Instance with filled responses mode: "print", // Required for print mode currentUser: viewerUserData, // Optional: For display purposes // Note: Callbacks are disabled in print mode // All steps displayed on one continuous page without sidebar // Files show detailed info (filename, size, type) instead of links }); // Loading state (can be used with any mode) createRunner("loading-container", { instance: instanceData, mode: "default", isLoading: true, // Shows loading spinner and disables step navigation currentUser: userData, onInstanceUpdated: (detail) => { console.log("Progress:", detail); // Update isLoading to false when ready // runnerWidget.isLoading = false; }, }); ``` ### Loading State The Runner widget supports a loading state that can be used with any mode to show a loading indicator and disable user interaction while data is being processed or fetched. **Configuration:** ```javascript const runnerWidget = createRunner("runner-container", { instance: instanceData, mode: "default", isLoading: true, // Shows loading spinner and disables step navigation currentUser: userData, onInstanceUpdated: (detail) => { console.log("Progress:", detail); }, }); // Update loading state dynamically runnerWidget.isLoading = false; // Hide loading spinner and re-enable navigation ``` **Features:** - āœ… **Loading Spinner:** Displays an animated spinner with "Loading..." text - āœ… **Disabled Navigation:** All step navigation (sidebar and mobile) is disabled - āœ… **Visual Overlay:** Semi-transparent overlay covers the entire widget - āœ… **Dynamic Control:** Can be toggled on/off programmatically at any time - āœ… **Mode Compatible:** Works with all runner modes (default, preview, admin, view-only, print) **Use Cases:** - Loading workflow data from backend - Processing form submissions - Saving progress to external systems - Waiting for validation responses - Any asynchronous operation that requires user to wait ### View-Only Mode: File and Signature Links In view-only mode, file uploads and signatures are displayed as clickable links instead of form inputs. This allows users to view and download the actual files and signatures that were submitted: ### Print Mode: Enhanced File and Signature Display In print mode, file uploads and signatures are displayed with detailed information instead of interactive elements, making them perfect for printed documents: **File Upload Display:** - **File Info Objects:** Shows complete metadata including filename, size (human-readable), file type, and modification date - **URL References:** Automatically extracts filename and file type from URLs when only URL is available - **Print-Friendly Format:** Clean, structured display without any interactive elements **Signature Display:** - **Embedded Images:** Signatures are displayed as images directly in the document - **Fallback Handling:** Graceful handling of missing or corrupted signature data - **No Interactive Elements:** Pure display mode suitable for printing **Example Print Mode File Display:** ``` šŸ“Ž File: contract_agreement.pdf šŸ“ Size: 2.3 MB šŸ“„ Type: PDF Document šŸ“… Modified: 12/15/2024, 2:30:15 PM ``` ```javascript // Example: Instance with file upload and signature responses const completedInstanceData = { id: "inst-123", workflowId: "wf-onboarding", name: "John Doe Onboarding", status: "completed", steps: [ { id: "step-1", title: "Document Upload", responses: [ { elementId: "resume-upload", value: "https://storage.example.com/files/john-doe-resume.pdf", // File URL answeredAt: new Date("2024-01-15T10:30:00Z"), }, { elementId: "signature-pad", value: "https://storage.example.com/signatures/john-doe-sig.svg", // Signature URL directly in value answeredAt: new Date("2024-01-15T10:35:00Z"), }, ], elements: [ { id: "resume-upload", type: "file_upload", label: "Upload Resume", required: true, }, { id: "signature-pad", type: "signature", label: "Digital Signature", required: true, }, ], }, ], completedSteps: ["step-1"], }; // When rendered in view-only mode: // - File upload shows: "šŸ“Ž filename.pdf" (clickable link that opens file in new tab) // - Signature shows: embedded signature image (same as print mode) ``` ## HTML Export Utility Begin Widgets includes a powerful HTML export utility that generates print-ready HTML from workflow instances. This is perfect for server-side PDF generation, email reports, and documentation. ### Overview The `generateInstanceHTML()` function takes a workflow `Instance` object and produces complete HTML that matches the appearance of the runner widget's print mode exactly. By default, it renders only the workflow steps and elements (just like print mode). Optionally, you can add metadata headers with instance information. ### Basic Usage ```typescript import { generateInstanceHTML } from "begin-widgets"; const result = generateInstanceHTML(myInstance); console.log(result.html); // Complete HTML string ready for PDF generation ``` ### With Options ```typescript const result = generateInstanceHTML(myInstance, { title: "Employee Onboarding Report", showTimestamps: true, // Add metadata header (not in print mode) customCSS: ` .print-layout { font-family: 'Times New Roman', serif; } `, }); ``` ### PDF Generation Example ```typescript const puppeteer = require("puppeteer"); async function generatePDF(instance) { const result = generateInstanceHTML(instance, { title: "Workflow Report", showTimestamps: true, }); const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setContent(result.html, { waitUntil: "networkidle0" }); await page.pdf({ path: "./report.pdf", format: "A4", printBackground: true, margin: { top: "20mm", right: "20mm", bottom: "20mm", left: "20mm" }, }); await browser.close(); } ``` ### Server-Side Usage ```javascript const express = require("express"); const { generateInstanceHTML } = require("begin-widgets"); app.get("/report/:instanceId", async (req, res) => { const instance = await getInstanceFromDatabase(req.params.instanceId); const result = generateInstanceHTML(instance, { title: `Report: ${instance.name}`, showTimestamps: true, }); res.setHeader("Content-Type", "text/html"); res.send(result.html); }); ``` ### Features - āœ… **Exact Print Mode Replica** - Matches runner widget print mode exactly - āœ… **All Question Types** - Text, select, radio, checkbox, file uploads, signatures - āœ… **File Metadata** - Shows filename, size, type, modification dates - āœ… **Signature Images** - Embedded signatures from provided URLs - āœ… **PDF-Ready** - Print media queries, page breaks, embedded CSS - āœ… **Server-Side Compatible** - No browser dependencies, works in Node.js - āœ… **Zero Dependencies** - Pure HTML/CSS output ### API Reference ```typescript interface HTMLExportOptions { title?: string; // Custom document title (default: instance.name) includeStyles?: boolean; // Include embedded CSS (default: true) customCSS?: string; // Additional CSS to inject showTimestamps?: boolean; // Show instance metadata header (default: false) } interface HTMLExportResult { html: string; // Complete HTML document title: string; // Document title used generatedAt: Date; // Generation timestamp } ``` ## TypeScript Support Begin Widgets includes comprehensive TypeScript definitions for full type safety and developer experience. ### Installing Types When you install `begin-widgets` from npm, the TypeScript declaration files are automatically included: ```bash npm install begin-widgets ``` ### Importing Types #### Option 1: Import Types with Functions (Recommended) ```typescript import { createBuilder, createRunner, type Workflow, type Instance, type Step, type StepElement, type QuestionElement, type ContentElement, } from "begin-widgets"; // Use the types for type safety const myWorkflow: Workflow = { id: "my-workflow", name: "My Workflow", steps: [], }; const myInstance: Instance = { id: "my-instance", workflowId: "my-workflow", name: "My Instance", status: "active", createdAt: new Date(), updatedAt: new Date(), steps: [], completedSteps: [], }; ``` #### Option 2: Import Types Only ```typescript import type { Workflow, Instance, Step, StepElement, QuestionElement, ContentElement, QuestionResponse, StepAssignment, BuilderConfig, RunnerConfig, } from "begin-widgets"; ``` #### Option 3: Dedicated Types Entry Point ```typescript import type { Workflow, Instance, StepElement, QuestionElement, ContentElement, BuilderConfig, RunnerConfig, } from "begin-widgets/types"; ``` ### Available Types | Type | Description | | ------------------ | ---------------------------------------- | | `Workflow` | Complete workflow template definition | | `Instance` | Workflow instance with data and progress | | `Step` | Individual workflow step | | `StepElement` | Union of all possible step elements | | `QuestionElement` | Form question element | | `ContentElement` | Content/display element | | `QuestionResponse` | User's answer to a question | | `StepAssignment` | Who a step is assigned to | | `StepStatus` | Current status of a step | | `BuilderConfig` | Configuration for the builder widget | | `RunnerConfig` | Configuration for the runner widget | | `Visibility` | Element visibility rules | | `VisibilityRule` | Individual visibility condition | > **Note:** The `Question` type is deprecated and only included for legacy support. Use `QuestionElement` for all new development. ### JavaScript Projects with JSDoc For JavaScript projects, you can still get type hints using JSDoc: ```javascript /** * @typedef {import('begin-widgets').Workflow} Workflow * @typedef {import('begin-widgets').Instance} Instance */ /** * @param {Workflow} workflow * @param {Instance} instance */ function processWorkflow(workflow, instance) { // Full intellisense and type checking here console.log(workflow.name); console.log(instance.status); } ``` ### UMD Bundle with Types When using the UMD bundle directly in the browser, you can still import types separately for TypeScript projects: ```html <!-- Runtime: UMD bundle --> <script src="https://unpkg.com/begin-widgets/dist/begin-widgets.umd.js"></script> <script> // Runtime usage const { createBuilder, createRunner } = Begin; </script> ``` ```typescript // Types: Import separately in TypeScript files import type { Workflow, Instance } from "begin-widgets"; ``` ### Type Safety Benefits - **Intellisense**: Full autocomplete in VS Code, WebStorm, and other IDEs - **Compile-time Checking**: Catch errors before runtime - **Documentation**: Types serve as inline documentation - **Refactoring**: Safe refactoring with type checking - **Zero Runtime Cost**: Types are compile-time only, no bundle size impact ## Project Structure ``` begin-widgets/ ā”œā”€ā”€ src/ │ ā”œā”€ā”€ models.ts # TypeScript interfaces │ ā”œā”€ā”€ lib.ts # Main library API │ ā”œā”€ā”€ builder-widget.ts # Workflow template builder component │ ā”œā”€ā”€ runner-widget.ts # Workflow runner component │ ā”œā”€ā”€ styles/ # Organized CSS styles for components │ │ ā”œā”€ā”€ base-styles.ts │ │ ā”œā”€ā”€ form-styles.ts │ │ ā”œā”€ā”€ section-styles.ts │ │ ā”œā”€ā”€ step-styles.ts │ │ ā”œā”€ā”€ modal-styles.ts │ │ └── index.ts │ └── main.ts # Entry point for development ā”œā”€ā”€ scripts/ │ └── build-html.js # Build script for production HTML ā”œā”€ā”€ dist/ # Generated files (after build) │ ā”œā”€ā”€ begin-widgets.umd.js │ └── index.html ā”œā”€ā”€ index.html # Development HTML (ES modules) ā”œā”€ā”€ vite.config.js # Vite configuration └── package.json ``` ## Development Commands ```bash # Start development server with hot reload npm run dev # Build the production bundle npm run build # Preview the production build npm run preview # Run tests (placeholder) npm test ``` ## Troubleshooting ### "Begin library not found" Error - **In Development:** Make sure you're using `npm run dev`, not `npm run preview` - **In Production:** Make sure you ran `npm run build` before `npm run preview` ### Module Loading Issues - **Development mode** uses ES modules and requires a modern browser - **Production mode** uses UMD bundle and works in older browsers ### Build Errors - Ensure TypeScript compiles without errors: `npx tsc --noEmit` - Check that all imports are correctly typed and available --- Let Begin Widgets streamline your application's workflows!