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

@sparrowengg/integrations-templates-frontend

v7.0.0-bulkify.7

Published

A comprehensive React component library for building integration templates with field mapping, triggers, and data import functionality. Built with TypeScript and Twigs React components.

Downloads

4,144

Readme

AppNest Templates - Integration Frontend Components

A comprehensive React component library for building integration templates with field mapping, triggers, and data import functionality. Built with TypeScript and Twigs React components.

📦 Installation

npm install @sparrowengg/integrations-templates-frontend
# or
yarn add @sparrowengg/integrations-templates-frontend

🚀 Quick Start

import { Mapping, IntegrationTemplate } from '@sparrowengg/integrations-templates-frontend';
import '@sparrowengg/integrations-templates-frontend/dist/es/index.css';

// Basic mapping example
function MyMappingComponent() {
  return (
    <Mapping
      integrationName="Salesforce"
      // ... mapping props
    />
  );
}

🏗️ Architecture

The library is organized into several main modules:

  • Mapping - Complex field mapping between survey data and integration fields
  • Single Mapping - Simplified single-step mapping with configuration
  • Triggers - Conditional trigger setup with filter conditions
  • Contact Import - Contact data import with scheduling and mapping
  • Dynamic Mapping - Dynamic field mapping capabilities
  • Filter - Filter components for data filtering
  • Cascader Dropdown - Hierarchical dropdown navigation
  • Integration Template - Main wrapper component that orchestrates all modules

📚 Components Documentation

Mapping Component

The Mapping component provides a comprehensive interface for mapping survey fields to integration fields with support for complex configurations, event setup, and field validation.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | havingTypeDropdown | boolean | ✅ | Whether to show integration field type dropdown | | onSaveMappingLoader | boolean | ✅ | Loading state for save operation | | surveyDetails | SurveyDetails | ✅ | Survey information object | | integrationName | string | ✅ | Name of the target integration | | fields | FieldType[] | ✅ | Array of mapping field configurations | | setFields | React.Dispatch<React.SetStateAction<FieldType[]>> | ✅ | State setter for fields | | integrationFields | IntegrationFieldType[] | ✅ | Available integration fields | | setIntegrationFields | React.Dispatch<React.SetStateAction<IntegrationFieldType[]>> | ✅ | State setter for integration fields | | apiURL | string | ❌ | API endpoint URL (defaults to SurveySparrow URL) | | token | string | ✅ | Authentication token | | accounts | AccountsFieldType | ✅ | Account selection configuration | | events | EventFieldType | ✅ | Event selection configuration | | actions | ActionsFieldType | ✅ | Action selection configuration | | isMappingPage | boolean | ✅ | Current page state (event setup vs mapping) | | surveyType | string | ✅ | Type of survey | | navigateMappingPage | (value?: boolean) => void | ✅ | Navigation handler | | customList | CustomListFieldType | ✅ | Custom list configuration | | oldResponse | OldResponseFieldType | ✅ | Old response handling configuration | | hasPreviousMapping | boolean | ✅ | Whether previous mapping exists | | onSaveHandler | () => void | ✅ | Save operation handler | | editField | EditField \| null | ✅ | Field being edited | | previousMappingHandler | (value?: boolean) => void | ✅ | Previous mapping navigation handler | | onDeleteHandler | (id: string \| number) => void | ❌ | Delete field handler | | draftHandler | (type: string \| null, editFieldId?: string \| number) => void | ✅ | Draft save handler | | configuration | ConfigurationObject | ✅ | Configuration setup object |

FieldType

| Property | Type | Required | Description | |----------|------|----------|-------------| | id | string | ✅ | Unique field identifier | | surveySparrowField | SelectOption \| null | ✅ | Selected survey field | | integrationField | SelectOption \| null | ✅ | Selected integration field | | integrationFieldType | SelectOption \| null | ✅ | Integration field type | | isEssentialField | boolean | ✅ | Whether field is required for integration | | essentialFieldLabel | string | ❌ | Label for essential field | | mappedType | SelectOption | ✅ | Field mapping type | | defaultValue | FormFieldValue | ❌ | Default field value | | dependency | Record<string, unknown> \| null | ✅ | Field dependencies |

Example

import { Mapping } from '@sparrowengg/integrations-templates-frontend';

function MappingExample() {
  const [fields, setFields] = useState([
    {
      id: "email_field",
      surveySparrowField: null,
      integrationField: null,
      integrationFieldType: null,
      isEssentialField: true,
      essentialFieldLabel: "Email",
      mappedType: { label: "Email", value: "email" },
      defaultValue: null,
      dependency: null
    }
  ]);

  const [integrationFields, setIntegrationFields] = useState([
    {
      id: "email",
      label: "Email Address",
      value: "email",
      type: "string"
    }
  ]);

  return (
    <Mapping
      havingTypeDropdown={true}
      onSaveMappingLoader={false}
      surveyDetails={{
        surveyName: "Customer Feedback Survey",
        surveyId: "survey_123"
      }}
      integrationName="Salesforce"
      fields={fields}
      setFields={setFields}
      integrationFields={integrationFields}
      setIntegrationFields={setIntegrationFields}
      token="your_auth_token"
      accounts={{
        hasAccounts: true,
        options: [{ label: "Main Account", value: "acc_1" }],
        value: null,
        onChangeHandler: (value) => console.log('Account selected:', value)
      }}
      events={{
        hasEvents: true,
        options: [{ label: "Contact Update", value: "contact_update" }],
        value: null,
        onChangeHandler: (value) => console.log('Event selected:', value)
      }}
      actions={{
        hasActions: true,
        options: [{ label: "Create Contact", value: "create_contact" }],
        value: null,
        onChangeHandler: (value) => console.log('Action selected:', value)
      }}
      isMappingPage={false}
      surveyType="standard"
      navigateMappingPage={(value) => console.log('Navigate to mapping:', value)}
      customList={{ hasCustomList: false, value: null, onChangeHandler: () => {} }}
      oldResponse={{ hasOldResponse: false, value: null, onChangeHandler: () => {} }}
      hasPreviousMapping={false}
      onSaveHandler={() => console.log('Mapping saved')}
      editField={null}
      previousMappingHandler={() => console.log('Go back')}
      draftHandler={(type, id) => console.log('Save draft:', type, id)}
      configuration={{
        hasConfiguration: false,
        configurationFields: [],
        configuredFields: {},
        title: "Event Configuration"
      }}
    />
  );
}

SingleMapping Component

The SingleMapping component provides a simplified mapping interface with configuration steps, ideal for straightforward integration scenarios.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | hasPreviousMapping | boolean | ❌ | Whether previous mapping exists | | integrationFields | IntegrationField[] | ✅ | Available integration fields | | configuration | SingleMappingConfiguration | ✅ | Configuration object | | token | string | ❌ | Authentication token | | isMappingPage | boolean | ✅ | Current page state | | navigateMappingPage | (value?: boolean) => void | ✅ | Navigation handler | | apiURL | string | ❌ | API endpoint URL | | surveyDetails | SurveyDetails | ✅ | Survey information | | onSaveHandler | (fields: any) => void | ✅ | Save handler | | setIntegrationFields | React.Dispatch<React.SetStateAction<any>> | ✅ | Integration fields setter | | hasExistingMapping | boolean | ✅ | Whether existing mapping is present | | importResponse | ImportResponse | ✅ | Import response configuration | | editField | any | ❌ | Field being edited | | previousMappingHandler | (value?: boolean) => void | ❌ | Previous mapping handler |

Example

import { SingleMapping } from '@sparrowengg/integrations-templates-frontend';

function SingleMappingExample() {
  const [integrationFields, setIntegrationFields] = useState([
    { id: 1, label: "Name", value: "name", type: "string" },
    { id: 2, label: "Email", value: "email", type: "email" }
  ]);

  return (
    <SingleMapping
      integrationFields={integrationFields}
      setIntegrationFields={setIntegrationFields}
      configuration={{
        importOptions: {
          showImportOptions: true,
          excludeResponse: {
            id: "exclude",
            label: "Exclude existing responses",
            ifChecked: () => "Existing responses will be excluded",
            ifUnchecked: () => "All responses will be included",
            fieldType: "checkbox",
            value: false,
            onChangeHandler: (value) => console.log('Exclude changed:', value)
          },
          options: [
            {
              id: 1,
              label: "Import All Data",
              value: "all",
              description: "Import all available data",
              type: null
            }
          ],
          onChangeHandler: (value) => console.log('Import option changed:', value)
        },
        hasConfiguration: true,
        configuredFields: {},
        configurationFields: [],
        onSaveHandler: () => console.log('Configuration saved')
      }}
      isMappingPage={false}
      navigateMappingPage={(value) => console.log('Navigate:', value)}
      surveyDetails={{
        surveyName: "Product Feedback",
        surveyId: "prod_survey_1"
      }}
      onSaveHandler={(fields) => console.log('Single mapping saved:', fields)}
      hasExistingMapping={false}
      importResponse={{
        hasImportResponse: true,
        value: { importMethod: "SEND_ALL_DATA" },
        onChangeHandler: (value) => console.log('Import response changed:', value)
      }}
    />
  );
}

Triggers Component

The Triggers component provides a comprehensive interface for setting up conditional triggers with filter conditions and notification settings.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | draftHandler | (type: string \| null, editFieldId?: string) => void | ✅ | Draft save handler | | onSaveTriggerLoader | boolean | ✅ | Loading state for save operation | | objects | ObjectsFieldType | ✅ | Object selection configuration | | accounts | AccountsFieldType | ✅ | Account selection configuration | | actions | ActionsFieldType | ✅ | Action selection configuration | | isTriggerPage | boolean | ✅ | Current page state | | navigateTriggerPage | (isTriggerPage: boolean) => void | ✅ | Page navigation handler | | previousMapping | boolean | ✅ | Whether previous mapping exists | | onSaveHandler | (editFieldId?: string) => void | ✅ | Save operation handler | | previousMappingHandler | () => void | ✅ | Previous mapping navigation | | surveyDetails | SurveyDetails | ✅ | Survey information | | hasNestedCondition | boolean | ✅ | Whether nested conditions are supported | | fields | TriggerField | ✅ | Trigger field configuration | | token | string | ✅ | Authentication token | | apiURL | string | ✅ | API endpoint URL | | setFields | (fields: TriggerField) => void | ✅ | Fields state setter | | shareRecipentOptions | SelectOption[] | ✅ | Share recipient options | | shareChannelOptions | SelectOption[] | ✅ | Share channel options | | triggerDetails | TriggerDetails | ✅ | Trigger details configuration | | setTriggerDetails | (details: TriggerDetails) => void | ✅ | Trigger details setter | | editField | EditField \| null | ✅ | Field being edited | | fieldOptions | SelectOption[] | ✅ | Available field options | | variableOptions | SelectOption[] | ✅ | Available variable options |

TriggerField

| Property | Type | Required | Description | |----------|------|----------|-------------| | id | string | ✅ | Unique trigger identifier | | filters | FilterGroup[] | ✅ | Array of filter groups |

FilterGroup

| Property | Type | Required | Description | |----------|------|----------|-------------| | id | string | ✅ | Filter group identifier | | conditions | FilterCondition[] | ✅ | Array of filter conditions | | operator | 'AND' \| 'OR' | ✅ | Logical operator between conditions |

Example

import { Triggers } from '@sparrowengg/integrations-templates-frontend';

function TriggersExample() {
  const [triggerFields, setTriggerFields] = useState({
    id: "trigger_1",
    filters: [
      {
        id: "group_1",
        conditions: [
          {
            id: "condition_1",
            field: { label: "Score", value: "score" },
            operator: { label: "Greater than", value: "gt" },
            value: 8
          }
        ],
        operator: "AND"
      }
    ]
  });

  const [triggerDetails, setTriggerDetails] = useState({
    shareChannel: { label: "Email", value: "email" },
    shareRecipient: { label: "Admin", value: "[email protected]" },
    shareType: { label: "Notification", value: "notification" }
  });

  return (
    <Triggers
      draftHandler={(type, id) => console.log('Save draft:', type, id)}
      onSaveTriggerLoader={false}
      objects={{
        hasObjects: true,
        options: [{ label: "Survey Response", value: "response" }],
        value: { label: "Survey Response", value: "response" },
        onChangeHandler: (value) => console.log('Object selected:', value)
      }}
      accounts={{
        hasAccounts: false,
        options: [],
        value: null,
        onChangeHandler: () => {}
      }}
      actions={{
        hasActions: true,
        options: [{ label: "Send Notification", value: "notify" }],
        value: { label: "Send Notification", value: "notify" },
        onChangeHandler: (value) => console.log('Action selected:', value)
      }}
      isTriggerPage={false}
      navigateTriggerPage={(value) => console.log('Navigate to trigger page:', value)}
      previousMapping={false}
      onSaveHandler={(id) => console.log('Trigger saved:', id)}
      previousMappingHandler={() => console.log('Go back')}
      surveyDetails={{
        surveyName: "Customer Satisfaction",
        surveyId: "csat_survey"
      }}
      hasNestedCondition={true}
      fields={triggerFields}
      token="auth_token"
      apiURL="https://api.example.com"
      setFields={setTriggerFields}
      shareRecipentOptions={[
        { label: "Admin", value: "[email protected]" },
        { label: "Manager", value: "[email protected]" }
      ]}
      shareChannelOptions={[
        { label: "Email", value: "email" },
        { label: "Slack", value: "slack" }
      ]}
      triggerDetails={triggerDetails}
      setTriggerDetails={setTriggerDetails}
      editField={null}
      fieldOptions={[
        { label: "Score", value: "score" },
        { label: "Category", value: "category" }
      ]}
      variableOptions={[
        { label: "Response ID", value: "response_id" },
        { label: "Respondent Email", value: "respondent_email" }
      ]}
    />
  );
}

ContactImport Component

The ContactImport component provides functionality for importing contact data with mapping, scheduling, and management capabilities.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | dashboardDescription | string | ✅ | Description text for dashboard | | existingImports | Array<CompletedImportTypes \| ScheduledImportTypes> \| null | ✅ | Existing import records | | hasPreviousMapping | boolean | ❌ | Whether previous mapping exists | | previousMappingHandler | (value?: boolean) => void | ✅ | Previous mapping handler | | onSaveHandler | () => void | ✅ | Save operation handler | | isContactMappingPage | boolean | ✅ | Current page state | | navigateMappingPage | (value?: boolean) => void | ✅ | Navigation handler | | contactImportField | ContactImportFieldType | ✅ | Contact import configuration | | setContactImportField | React.Dispatch<React.SetStateAction<ContactImportFieldType>> | ✅ | Configuration setter | | listSegmentOptions | SelectOption[] | ✅ | List segment options | | integrationName | string | ✅ | Integration name | | contactProperties | ContactProperty[] | ✅ | Available contact properties | | invitePortal | InvitePortalType | ✅ | Invite portal configuration |

ContactImportFieldType

| Property | Type | Required | Description | |----------|------|----------|-------------| | configure | ConfigureObject \| null | ✅ | Configuration settings | | description | string \| null | ✅ | Import description | | id | string \| number \| null | ✅ | Import identifier | | fields | ContactFieldType[] | ✅ | Field mappings | | invitePortal | boolean | ✅ | Whether to invite to portal |

Example

import { ContactImport } from '@sparrowengg/integrations-templates-frontend';

function ContactImportExample() {
  const [contactImportField, setContactImportField] = useState({
    configure: null,
    description: null,
    id: null,
    fields: [],
    invitePortal: false
  });

  return (
    <ContactImport
      dashboardDescription="Manage your contact imports and sync data with your integration."
      existingImports={[]}
      hasPreviousMapping={false}
      previousMappingHandler={() => console.log('Go back')}
      onSaveHandler={() => console.log('Import saved')}
      isContactMappingPage={false}
      navigateMappingPage={(value) => console.log('Navigate:', value)}
      contactImportField={contactImportField}
      setContactImportField={setContactImportField}
      listSegmentOptions={[
        { label: "All Contacts", value: "all" },
        { label: "Active Subscribers", value: "active" }
      ]}
      integrationName="Mailchimp"
      contactProperties={[
        { id: 1, label: "Email", value: "email", type: "email" },
        { id: 2, label: "First Name", value: "first_name", type: "text" }
      ]}
      invitePortal={{
        hasInvitePortal: true,
        value: false,
        onChangeHandler: (value) => console.log('Invite portal:', value)
      }}
    />
  );
}

IntegrationTemplate Component

The IntegrationTemplate is the main orchestrating component that manages the flow between different integration steps including mapping, triggers, and dashboard views.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | singleMapping | SingleMappingType | ❌ | Single mapping configuration | | draftHandler | (type: string \| null) => void | ✅ | Draft save handler | | onMappingEditHandler | (field: unknown) => void | ✅ | Mapping edit handler | | fieldOptions | FieldOptionsType | ✅ | Available field options | | triggerEnabled | boolean | ✅ | Whether triggers are enabled | | mappingEnabled | boolean | ✅ | Whether mapping is enabled | | mappingComponent | React.ReactElement | ✅ | Mapping component instance | | singleMappingComponent | React.ReactElement | ❌ | Single mapping component instance | | mapping | MappingState | ✅ | Mapping state object | | triggerComponent | React.ReactElement | ✅ | Trigger component instance | | trigger | TriggerState | ✅ | Trigger state object | | integrationName | string | ✅ | Integration name | | onDeleteHandler | (id: string \| number) => void | ❌ | Delete handler | | toggleDashboardField | (id: string \| number, status: boolean) => void | ❌ | Dashboard field toggle | | dashboardDescription | string | ✅ | Dashboard description | | mappingDescription | string | ✅ | Mapping description | | triggerDescription | string | ✅ | Trigger description | | handlePreviousNavigation | () => void | ✅ | Previous navigation handler | | surveyType | string | ❌ | Survey type | | syncMapping | (id: string \| number) => void | ❌ | Sync mapping handler |

Example

import { IntegrationTemplate, Mapping, Triggers } from '@sparrowengg/integrations-templates-frontend';

function IntegrationTemplateExample() {
  const [mappingFields, setMappingFields] = useState({ type: "MAPPING", fields: [] });
  const [triggerFields, setTriggerFields] = useState([]);

  const mappingComponent = (
    <Mapping
      // ... mapping props
      onSaveHandler={() => console.log('Mapping saved')}
    />
  );

  const triggerComponent = (
    <Triggers
      // ... trigger props
      onSaveHandler={() => console.log('Trigger saved')}
    />
  );

  return (
    <IntegrationTemplate
      draftHandler={(type) => console.log('Save draft:', type)}
      onMappingEditHandler={(field) => console.log('Edit mapping:', field)}
      fieldOptions={[
        { label: "Email", value: "email" },
        { label: "Name", value: "name" }
      ]}
      triggerEnabled={true}
      mappingEnabled={true}
      mappingComponent={mappingComponent}
      mapping={{
        mappedFields: mappingFields,
        setMappedFields: setMappingFields
      }}
      triggerComponent={triggerComponent}
      trigger={{
        mappedFields: triggerFields,
        setMappedFields: setTriggerFields
      }}
      integrationName="Salesforce"
      dashboardDescription="Manage your Salesforce integration configurations."
      mappingDescription="Map survey fields to Salesforce objects."
      triggerDescription="Set up automated triggers based on survey responses."
      handlePreviousNavigation={() => console.log('Navigate back')}
    />
  );
}

🎨 Styling

The library includes built-in CSS styles. Make sure to import the stylesheet:

import '@sparrowengg/integrations-templates-frontend/dist/es/index.css';

All components use the Twigs React design system and support custom theming through the ThemeProvider.

🔧 Advanced Usage

Custom Theme Configuration

import { ThemeProvider } from '@sparrowengg/twigs-react';

const customTheme = {
  fonts: {
    body: "Inter, sans-serif",
    heading: "Inter, sans-serif"
  },
  colors: {
    primary500: "#4A9CA6"
  }
};

function App() {
  return (
    <ThemeProvider theme={customTheme}>
      {/* Your components */}
    </ThemeProvider>
  );
}

Error Handling

Components provide error states and validation feedback:

// Field with validation error
{
  id: "email",
  type: "input",
  label: "Email",
  value: "invalid-email",
  changeFieldValue: handleChange,
  required: true,
  // Error will be shown if validation fails
}

Loading States

Most components support loading states for async operations:

<Mapping
  onSaveMappingLoader={true} // Shows loading spinner on save button
  // ... other props
/>

🤝 TypeScript Support

The library is built with TypeScript and provides comprehensive type definitions for all components and props. Import types as needed:

import type { 
  MappingProps, 
  TriggerProps,
  SelectOption,
  FieldType 
} from '@sparrowengg/integrations-templates-frontend';

📖 API Reference

Common Types

SelectOption

type SelectOption = {
  label: string;
  value: string | number;
  type?: string;
};

SurveyDetails

type SurveyDetails = {
  surveyName: string;
  surveyId: string | number;
};

FormFieldValue

type FormFieldValue = string | number | boolean | null | SelectOption | SelectOption[];