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

@voxket-ai/events-sdk

v1.0.38

Published

Event registration and ticketing widget SDK

Readme

@voxket-ai/events-sdk

Enterprise embeddable event registration, ticketing, and attendee self-service portal SDK for Voxket.

npm version License: MIT


Features

  • Multiple Display Formats: Seamlessly embed as an inline widget, a floating corner popup, or a fullscreen modal.
  • Interactive Corner Snapping: In popup mode, attendees can slide/drag the collapsed widget to any screen corner (bottom-right, bottom-left, top-right, top-left).
  • Shadow DOM Isolation: Runs inside an isolated Shadow Root so host CSS styles and framework resets never bleed in or break the widget layout.
  • Configurable Dark & Light Themes: Full host-configured dark mode (bg-black text-white) and light mode with custom brand primary colors and typography.
  • Event Callbacks (onError, onRegister): Native typed callbacks to easily display host toast notifications, trigger analytics, or redirect users.
  • Attendee Self-Service Portal: Attendees can log in, request OTP/verification codes, update registration fields, upload documents, and purchase add-ons.
  • Draft Auto-save & Instant Recovery: Automatically tracks in-progress form inputs and seamlessly recovers drafts via xref_id or email.
  • Configurable Network Timeout: Built-in 2-minute (120,000 ms) timeout across all API operations to handle slow mobile networks cleanly.
  • Framework Agnostic & React Support: Usable via vanilla JavaScript (EventWidgetClient) or directly as a declarative React component (EventWidget).

Installation

npm install @voxket-ai/events-sdk

Or via Yarn / pnpm:

yarn add @voxket-ai/events-sdk
# or
pnpm add @voxket-ai/events-sdk

Quick Start

1. React Applications

Import EventWidget and pass your WidgetConfig:

import React from 'react';
import { EventWidget, type WidgetConfig } from '@voxket-ai/events-sdk';

export function RegistrationSection() {
  const config: WidgetConfig = {
    eventSlug: 'fogsi-yuva_2026',
    baseUrl: 'https://api.voxket.com',
    displayMode: 'popup', // 'popup' | 'widget' | 'fullscreen'
    position: 'bottom-right',
    themeMode: 'light', // 'light' | 'dark'
    theme: {
      primaryColor: '#8b5cf6',
      fontFamily: 'Inter, system-ui, sans-serif'
    },
    // Fired when registration is completed
    onRegister: (data) => {
      console.log('Registered successfully:', data);
      alert(`Registration confirmed! Reference: ${data.payload.xref_id || 'N/A'}`);
    },
    // Fired on validation, submission, or network failure
    onError: (err) => {
      console.error('Widget error:', err);
      alert(`Error [${err.type}]: ${err.message}`);
    }
  };

  return <EventWidget config={config} />;
}

2. Vanilla JavaScript / HTML

Use EventWidgetClient to mount and manage the widget programmatically:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Event Registration</title>
</head>
<body>
  <!-- Mount target for inline widget or popup anchor -->
  <div id="voxket-widget-container"></div>

  <script type="module">
    import { EventWidgetClient } from '@voxket-ai/events-sdk';

    const client = new EventWidgetClient({
      eventSlug: 'fogsi-yuva_2026',
      baseUrl: 'https://api.voxket.com',
      displayMode: 'popup',
      position: 'bottom-right',
      themeMode: 'dark', // Enable dark mode
      theme: {
        primaryColor: '#6366f1'
      },
      onRegister: (data) => {
        console.log('Registration complete:', data);
      },
      onError: (error) => {
        console.error('Error occurred:', error.message);
      }
    });

    // Mount to the DOM
    client.mount('voxket-widget-container');

    // Dynamically update configuration without unmounting
    // client.updateConfig({ position: 'bottom-left' });

    // Clean up when leaving the page
    // client.unmount();
  </script>
</body>
</html>

3. Abstract Submission Page

Set isAbstract: true to render a dedicated abstract page. It uses the same form types and form UI as registration.

  • No Attendee Login tab. The page shows only the form types.
  • Review fields are shown. Fields with is_review: true or false both appear. Review fields get a card that takes either a file or text, one at a time (Send text only / Send file toggle).
  • Review uploads authenticate by email. They go to POST /api/portal/{slug}/me/submissions/ with the email entered in the form; no bearer token is sent.
  • The submit call carries a flag. The form posts to the registration submit API with accept_review_file: true, and draft saves send the same flag.
  • After submitting: a "Submitted" screen with a Submit Again button. There is no payment step.

React

<EventWidget
  config={{
    eventSlug: 'fogsi-yuva_2026',
    baseUrl: 'https://api.voxket.com',
    displayMode: 'widget', // full-page
    isAbstract: true,
    theme: { primaryColor: '#c026d3' },
    onEvent: (name, payload) => console.log(name, payload),
    onError: (err) => console.error(err.message),
  }}
/>

Vanilla JS

const client = new EventWidgetClient({
  eventSlug: 'fogsi-yuva_2026',
  baseUrl: 'https://api.voxket.com',
  displayMode: 'fullscreen',
  isAbstract: true,
});
client.mount('voxket-widget-container');

// Switch an existing widget between registration and abstract
// client.updateConfig({ isAbstract: false });

To host both pages, render one widget per page (or route) and set isAbstract on the abstract one only.


Configuration Reference (WidgetConfig)

All available options for the WidgetConfig object:

| Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | eventSlug | string | (Required) | The unique identifier/slug of the event in Voxket. | | baseUrl | string | (Required) | API base URL for Voxket backend endpoints. | | displayMode | 'popup' \| 'widget' \| 'fullscreen' | 'widget' | Layout style: floating popup badge, inline embedded container, or full viewport modal. | | position | WidgetPosition | 'bottom-right' | Starting corner for popup mode. Options: 'bottom-right', 'bottom-left', 'top-right', 'top-left', 'right-bottom', 'left-bottom', 'right-top', 'left-top'. | | themeMode | 'light' \| 'dark' | 'light' | Controls the base color scheme (clean white/gray or deep black #000 with high-contrast text). | | theme | object | {} | Detailed appearance customization (see below). | | theme.primaryColor | string | '#2563eb' | Brand color used for primary buttons, tabs, highlights, and headers. | | theme.fontFamily | string | Host page's font | Leave it out to use the host page's font. Pass a font family CSS string (e.g. 'Inter, sans-serif') to use a different one. See Matching the Host Site's Design. | | theme.mode | 'light' \| 'dark' \| 'blue' \| 'white' \| 'custom' | 'light' | Preset theme mode alias. | | isAbstract | boolean | false | Abstract submission page: no attendee login, shows is_review fields, adds accept_review_file: true on submit. See Abstract Submission Page. | | headerBannerImage | string | undefined | Banner image on the right of the top header, scaled to the header's height; its left edge fades into the header's theme-color gradient. See Banner & Background Images. | | backgroundImage | string | undefined | Faded background image behind the form-types list, the form page and the attendee login/portal. It stays still while content scrolls. See Banner & Background Images. | | width | string | undefined | Custom width override (e.g. '500px', '100%'). | | height | string | undefined | Custom height override (e.g. '700px', '650px'). | | timeoutMs | number | 120000 (2 min) | Network request timeout in milliseconds before triggering onError. | | debug | boolean | false | Enables verbose debug logging in the browser console. | | onRegister | (data: RegistrationSuccessPayload) => void | undefined | Callback fired when an attendee completes registration successfully. | | onRegistered | (data: RegistrationSuccessPayload) => void | undefined | Alias for onRegister. | | onError | (error: WidgetErrorPayload) => void | undefined | Callback fired on validation, submission, network, or schema load errors. | | onEvent | (eventName: string, payload: any) => void | undefined | Optional generic event bus for internal widget lifecycle events. |

Common onEvent names:

| Event | When it fires | | :--- | :--- | | form_loaded | The form schema has loaded. | | draft_saved | Form progress was auto-saved. | | submitted | The form was submitted (registration or abstract). | | review_submission_uploaded | A review field was submitted from the abstract page. | | portal_submission_uploaded | A review field was submitted from the attendee portal. | | portal_file_deleted | The attendee deleted an uploaded file in the portal. | | attendee_profile_loaded | The attendee portal profile has loaded. |


Event Callbacks & Toast Notifications

The SDK exposes dedicated callback functions so host applications can handle state transitions and show native toast notifications.

1. onError

Fires whenever an operation fails (form validation failure, network disconnect, timeout, attendee login error, or profile update issue):

onError: (err: WidgetErrorPayload) => void;

Payload Schema:

interface WidgetErrorPayload {
  type: 'submit_error' | 'schema_load' | 'login_error' | 'profile_update_error' | 'file_upload_error' | 'network_error' | string;
  message: string;
  error?: any;
}

Toast Example (React Toastify / Sonner / AntD):

const config: WidgetConfig = {
  // ...
  onError: (err) => {
    // Show toast in your host application
    toast.error(err.message, {
      description: `Error code: ${err.type}`
    });
  }
};

2. onRegister (or onRegistered)

Fires when an attendee successfully submits their registration form:

onRegister: (data: RegistrationSuccessPayload) => void;

Payload Schema:

interface RegistrationSuccessPayload {
  registrationType: string | number; // Selected ticket type
  payload: Record<string, any>;      // Form field responses submitted
  response?: any;                    // Raw backend API response
  paymentUrl?: string | null;        // Gateway URL if payment is required
}

Toast & Redirect Example:

const config: WidgetConfig = {
  // ...
  onRegister: (data) => {
    toast.success(`Registration received for ${data.registrationType}!`);

    if (data.paymentUrl) {
      console.log('Payment gateway URL ready:', data.paymentUrl);
    }
  }
};

Draggable Corner Positioning (Popup Mode)

When displayMode: 'popup' is active:

  1. The widget renders as a compact floating badge at the configured position (e.g. bottom-right).
  2. Move Handle: Hovering over the badge reveals a corner drag handle (Move icon at the top-left of the badge).
  3. Corner Snapping: Clicking and dragging the badge moves it across the screen; releasing snaps it to the nearest corner (bottom-right, bottom-left, top-right, or top-left).
  4. Once the popup is opened into full view, positioning is locked to prevent accidental movement during form completion.

Dark Mode Support

Theme mode is configured by the host application via themeMode:

const config: WidgetConfig = {
  eventSlug: 'fogsi-yuva_2026',
  baseUrl: 'https://api.voxket.com',
  themeMode: 'dark', // 'dark' | 'light'
  theme: {
    primaryColor: '#8b5cf6'
  }
};
  • When set to 'dark', all views—Ticket Selector, Attendee Portal, Dynamic Form Inputs, Payment Screens, and Error Modals—render in high-contrast deep black (#000000) and dark zinc tones with crisp borders.
  • Attendees cannot override the theme from within the widget headers; theme configuration is strictly controlled by your application config.

Registration Number & ?rn= Success Link

  • After a successful submit, the widget shows the registration_number from the submit response with a Copy button. It appears on both the success screen and the "complete your payment" screen.
  • If the page URL has ?rn=<registration number> (for example, the URL the payment gateway redirects back to), the widget opens straight on the success screen with that number. Popup mode opens automatically. Back removes rn from the URL and returns to the form types.
https://your-site.com/register?rn=FOGS-2026-00030

Banner & Background Images

const config: WidgetConfig = {
  eventSlug: 'fogsi-yuva_2026',
  baseUrl: 'https://api.voxket.com',
  theme: { primaryColor: '#c026d3' },
  headerBannerImage: 'https://i.postimg.cc/Hk02BDTh/image.png',
  backgroundImage: 'https://i.postimg.cc/DZmb4dtH/Screenshot-2026-09-24-200659.png',
};

| Prop | Where it shows | Behaviour | | :--- | :--- | :--- | | headerBannerImage | Right side of the top header, on every view (registration, attendee login, abstract) | Scaled to the header's height and never makes the header taller. Its left edge fades into the header gradient. Uses at most 65% of the header width; on narrow screens the image is cropped from the left. | | backgroundImage | Behind the form-types list, the form page and the attendee login/portal | Covered by a page-colored overlay so content stays readable; the overlay follows themeMode (light or dark). Stays still while content scrolls. Cards and form inputs keep their normal colors. |

  • The header always uses a theme-color gradient, whether or not a banner is set.
  • The tabs row is not affected by either image; it keeps the light/dark theme color.
  • Both images are optional. Leave them out for a plain gradient header and a solid page background.

Matching the Host Site's Design

The widget renders inside a Shadow DOM, so the host site's classes (Tailwind, shadcn, global CSS) never reach it and never break it. The host site can still restyle it in two ways. Both are opt-in: if the host site sets nothing, the widget looks exactly as before.

1. Fonts

The widget uses the host page's font by default, with nothing to configure. To use a different font, pass it in the config:

theme: { fontFamily: 'Inter, sans-serif' }

Headings use the same font unless the host page sets --vx-font-heading. Both can be set as CSS variables anywhere on the host page (:root works; they pass into the Shadow DOM), and they take priority over theme.fontFamily:

:root {
  --vx-font-family: var(--font-sans);      /* body text, inputs, buttons */
  --vx-font-heading: var(--font-heading);  /* titles and headings */
}

2. Element styles with ::part()

Key elements carry a part name. Target them from the host site's CSS through the widget host element [data-voxket-shadow-host]. These rules override the widget's own styles, including hover and focus states you target yourself (::part(card):hover, ::part(input):focus).

[data-voxket-shadow-host]::part(card) {
  border-radius: 1.75rem;
  border: 1px solid var(--border);
  box-shadow: none;
}
[data-voxket-shadow-host]::part(card-title) { color: var(--foreground); }
[data-voxket-shadow-host]::part(button-primary) { border-radius: 9999px; }

| Area | Part names | | :--- | :--- | | Whole widget | widget, launcher (popup "Join" button) | | Form-types list | page, header, header-title, header-subtitle, tabs, tab, tab-active, list, search (title + search toolbar), list-title, list-count, search-input, empty-state, card-grid | | Form-type card | card, card-category, card-seats, card-title, card-price, card-tax, card-description, card-perks, card-button | | Registration form | form-page, form-header, back-button, form-type-name, form-type-price, form, form-intro, form-title, notice, notice-title, form-card (card holding all fields), field (one section per field), field-label, field-description, upload, review-upload, submit-button | | Result screens | screen, screen-payment, screen-success, screen-error, screen-header, screen-header-title, screen-title, screen-message, registration-number, copy-button | | Attendee portal | portal, portal-card (login / get code / set password card, and every profile card), profile-card, details-card, addons-card, logout-button, portal-title, back-button, field-label, upload, submit-button | | Shared | input (text inputs, selects, textareas), select, textarea, button, button-primary, button-secondary, button-link |

Notes:

  • ::part() cannot reach inside a part (::part(card) h3 does not work). Use the dedicated part (::part(card-title)).
  • Many inputs have an icon on the left. Avoid overriding padding on ::part(input), or the text will overlap the icon.
  • The widget's colors are still driven by theme.primaryColor and themeMode. Rules you add apply in both light and dark mode.

Client API Methods (EventWidgetClient)

When using the vanilla JavaScript / non-React API:

| Method | Description | | :--- | :--- | | mount(container: HTMLElement \| string) | Mounts the widget into a DOM container element or element ID. | | updateConfig(newConfig: Partial<WidgetConfig>) | Merges new configuration values into the running widget without remounting. | | setConfig(newConfig: WidgetConfig) | Replaces the entire widget configuration. | | unmount() | Cleanly destroys the React root, removes DOM nodes, and releases event listeners. |


TypeScript Exports

All primary types are exported directly from the package:

import {
  EventWidget,
  EventWidgetClient,
  type WidgetConfig,
  type WidgetPosition,
  type ThemeMode,
  type RegistrationSuccessPayload,
  type WidgetErrorPayload
} from '@voxket-ai/events-sdk';

License

MIT © Voxket