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

@singlebase/xcrm-support-form

v0.2.0

Published

A SBC native support ticket web component for Frontdesk

Readme

xcrm-support-form

FOR RESERVED ACCESS ONLY

A SBC native support-ticket web component. Plain JavaScript, CSS and HTML.

FOR RESERVED ACCESS ONLY

Integration

Create a form in Tickets → Support forms, allow your website's origin, and use its UUID in form-id.

Load the published package from a CDN:

<script type="module" src="https://cdn.jsdelivr.net/npm/@singlebase/[email protected]/xcrm-support-form.js"></script>

<xcrm-support-form
  form-id="YOUR-FORM-UUID"
  member-ext-id="YOUR-MEMBER-EXTERNAL-ID"
  customer-ext-id="YOUR-CUSTOMER-EXTERNAL-ID"
  form-title="How can we help?"
  categories="Billing, Account, Technical"
  category-type="select"
  request-types="Question, Problem, Feature request"
  request-type-type="radio"
  accent="#0369a1"
  radius="8"
></xcrm-support-form>

With npm, after the package is published:

npm install @singlebase/xcrm-support-form
import '@singlebase/xcrm-support-form';

Use customer-ext-id, member-ext-id, or both; they resolve to records within the form's store. Use an explicit closing tag.

Options

Attributes can be changed after the component mounts. For visibility options, use the string "false" to hide a field.

Connection

| Attribute | Default | Description | |---|---|---| | form-id | Required | Form UUID4. Alias: form_id. | | customer-ext-id | Empty | Customer external ID. Alias: customer_ext_id. | | member-ext-id | Empty | Member external ID. Alias: member_ext_id. | | prefetch | Absent | Presence starts verification on connection. Otherwise starts on first focus or submission. |

Fields

| Attribute | Default | Description | |---|---|---| | default-name | Empty | Editable initial name. | | default-email | Empty | Editable initial email. | | show-phone | true | Show the optional phone field. | | show-title | true | Show the required message title. | | default-title | Support request | Subject sent when the title field is hidden. | | show-category | true | Show Category. | | categories | General Inquiry, Billing, Technical issue, Account, Feedback | Comma-separated category choices. Empty hides radio/dropdown categories. | | category-type | radio | radio chips, select dropdown, or text input. | | default-category | First choice | Initial selection, or initial text in text mode. | | request-types | Empty | Comma-separated request-type choices. Empty hides radio/dropdown request types. | | request-type-type | radio | radio, select, or text. | | show-request-type | true | Set false to hide Request type while keeping its configuration. | | default-request-type | First choice | Initial selection, or initial text in text mode. | | min-length | 10 | Minimum message length. The ticket API requires at least 10 characters. | | max-length | 2000 | Maximum message length. The ticket API permits up to 5000 characters. |

Radios allow clearing the selected choice. Dropdowns include an empty option. Text category/request-type fields accept arbitrary values up to 100 characters; without an explicit default their initial text is empty. Name, email, and message are required. Phone is optional.

Labels and placeholders

| Label attribute | Default | Placeholder attribute | Default | |---|---|---|---| | name-label | Name | name-placeholder | Ada Lovelace | | email-label | Email | email-placeholder | [email protected] | | phone-label | Phone | phone-placeholder | +1 555 010 0199 | | category-label | Category | category-placeholder | Enter a category | | request-type-label | Request type | request-type-placeholder | Enter a request type | | title-label | Message title | title-placeholder | Short summary of the issue | | message-label | Message content | message-placeholder | What happened, what you expected, and any steps to reproduce. |

Category/request-type placeholders apply to text inputs.

Text

| Attribute | Default | |---|---| | eyebrow | Support | | form-title | Contact support | | form-description | Tell us what's going on. We usually reply within one business day. | | submit-label | Send request | | footnote | We'll reply to the email above. | | thanks-title | Thanks for reaching out | | thanks-message | We've received your message and will get back to you shortly. | | new-message-label | Send New Message | | error-title | Your message wasn't sent. | | error-message | Something went wrong. Please try again. | | retry-label | Try again |

An empty eyebrow, title, description, or footnote hides that text. Empty all three header attributes to hide the header.

Appearance

| Attribute | Default | Values | |---|---|---| | theme | light | light, dark, auto (visitor's device preference). | | accent | #111111 | CSS color; button text contrast is chosen automatically. | | radius | 4 | Corner radius from 0–12 pixels; the card adds 6 pixels. | | density | comfortable | comfortable, compact. | | dir | Inherited | Standard HTML direction: ltr or rtl. |

CSS custom properties can override the appearance:

| Properties | Purpose | |---|---| | --sf-font, --sf-mono | Main and monospace font stacks. | | --sf-bg, --sf-sunk | Card and input/footer backgrounds. | | --sf-ink, --sf-muted | Main and secondary text colors. | | --sf-line, --sf-line-strong | Border colors. | | --sf-accent, --sf-on-accent | Accent and button text colors. | | --sf-danger, --sf-success | Error and success colors. | | --sf-radius | Corner radius as a CSS length. | | --sf-max-width | Card width limit; default 520px. | | --sf-shadow | Card box shadow. |

xcrm-support-form {
  --sf-font: system-ui, sans-serif;
  --sf-max-width: 600px;
}
xcrm-support-form::part(submit) { width: 100%; }

Available ::part() names: card, header, eyebrow, title, description, field, label, input, select, textarea, chip, chip-selected, error, alert, footer, submit, footnote, success, success-icon, new-message.

Slots replace header, footnote, or success content:

<xcrm-support-form form-id="YOUR-FORM-UUID">
  <span slot="footnote">See our <a href="/privacy">privacy policy</a>.</span>
</xcrm-support-form>

JavaScript

const form = document.querySelector('xcrm-support-form');
form.values = { name: 'Ann Lee', email: '[email protected]' };
form.customerExtId = 'customer-external-id';
form.addEventListener('xcrm-support-form:success', event => {
  console.log(event.detail.ticketId);
});

| Property or method | Description | |---|---| | formId, baseUrl | Get/set the form UUID and API base URL. | | customerExtId, memberExtId | Get/set external IDs. Aliases: customer_ext_id, member_ext_id. | | values | Get all values or set a partial object: name, email, phone, subject, category, requestType, message. | | state | Read-only: idle, sending, error, success. | | submit() | Validate and submit; returns a promise of Response or undefined on failure/cancellation without a response. | | reset() | Keep name/email, clear other values, and prepare fresh verification. | | messages | Override messages using nameRequired, emailInvalid, phoneInvalid, titleRequired, contentMin, contentMax, sending, sent. Length messages support {min} / {max}. | | fetch | Replace the fetch transport. | | transformPayload | Sync/async payload transformation before submission. The ticket endpoint accepts only its supported fields. |

ESM exports: XcrmSupportForm, SupportForm (alias), DEFAULT_BASE_URL, SUPPORT_FORM_DEFAULTS. TypeScript declarations are included.

Events

Events bubble across Shadow DOM.

| Event | Detail | |---|---| | xcrm-support-form:submit | {payload}; cancelable with preventDefault(). | | xcrm-support-form:success | {payload, response, ticketId?}. | | xcrm-support-form:error | {kind, status?, response?}; kind is network, server, rate-limit, or challenge. | | xcrm-support-form:change | {field, value}. | | xcrm-support-form:reset | Empty object. |

Custom transports and compatibility

| Attribute | Default | Description | |---|---|---| | site | Empty | Legacy site identifier, used when form-id is absent. | | challenge-url | Derived from form ID/base URL | Override the challenge endpoint. Legacy mode appends ?site=…. | | submit-url | Derived from form ID/base URL | Override the submission endpoint. | | credentials | omit | Fetch mode: omit, same-origin, include. |