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 🙏

© 2025 – Pkg Stats / Ryan Hefner

pxsol-booking-search-widget

v0.3.10

Published

Embeddable booking engine search widget with React and Web Component builds.

Readme

@pxsol/booking-search-widget

Embeddable booking engine search widget that ships a React component and a framework-agnostic Web Component. Both builds reuse the same headless state utilities and formatting helpers so you can embed the widget inside modern React apps or legacy pages with a single configuration.

Features

  • Airbnb-style search form with date range, guests/rooms, POS, language, currency, and product selector.
  • Emits stable lifecycle events (ready, change, validate_error, search_start, search_success, search_error).
  • Integrates with the Pxsol Search API via client-side fetch calls using a public token.
  • Shadow DOM styling for the Web Component with themable CSS variables (--yw-bg, --yw-fg, --yw-accent).
  • Dual outputs: React (ESM + CJS, peer React) and Custom Element (ESM + IIFE legacy bundle).
  • Headless helpers for formatting, validation, and request payload creation.

Installation

npm install @pxsol/booking-search-widget
# or
pnpm add @pxsol/booking-search-widget

Scripts

  • npm run build – produce all distribution bundles via tsup.
  • npm run dev – watch builds for local iteration.
  • npm run typecheck – static analysis using tsc --noEmit.
  • npm run demo – build once and launch a static server at http://localhost:4173.

Local demo

npm run demo

The command runs a one-off build and serves demo/index.html plus the compiled bundles from dist/. Visit http://localhost:4173 to interact with the widget, inspect emitted events, and iterate on configuration quickly.

React usage

import React from 'react';
import { BookingSearchWidget } from 'pxsol-booking-search-widget';

// ✅ CSS styles are automatically included - no need to import CSS separately

const config = {
  token: 'PUBLIC_SEARCH_TOKEN',
  theme: 'light',
  locale: 'es',
  currency: 'ARS',
  pos: 'HotelEscuela',
  productId: 2475,
  initialStart: '2024-07-01',
  initialEnd: '2024-07-05',
  onEvent: (event) => {
    if (event.type === 'search_success') {
      console.log('Search result', event.payload);
    }
  },
};

export function Demo() {
  return <BookingSearchWidget {...config} />;
}

Web Component usage

Modern browsers (ES Modules)

<script type="module">
  import 'pxsol-booking-search-widget/wc';
</script>

<your-widget
  token="PUBLIC_SEARCH_TOKEN"
  theme="dark"
  locale="es"
  currency="ARS"
  pos="HotelEscuela"
  product-id="2475"
  initial-start="2024-07-01"
  initial-end="2024-07-05"
></your-widget>

<script>
  document.querySelector('your-widget').addEventListener('yw:event', (event) => {
    console.log('Widget event', event.detail);
  });
</script>

Legacy pages (IIFE bundle)

<script src="/dist/your-widget.iife.js"></script>
<your-widget token="PUBLIC_SEARCH_TOKEN"></your-widget>

The IIFE build self-registers the custom element and exposes a registerYourWidget() helper when needed.

Minimal demo snippet

See demo/index.html for a copy-paste ready template that logs widget events to the screen. The page is served automatically by npm run demo.

For detailed integration guides (React via npm and plain HTML via CDN), read docs/INTEGRATION.md.

Events

| Event | Payload | Description | | --- | --- | --- | | ready | { state: WidgetState } | Widget is mounted and hydrated. | | change | { state: WidgetState } | Any user change to the internal state. | | validate_error | { valid: false; errors: Record<string, string> } | Validation failed prior to calling the API. | | search_start | SearchRequest | Outgoing payload before calling the API. | | search_success | { request: SearchRequest; response: SearchResponse } | Successful response from the API. | | search_error | { request: SearchRequest; error: Error } | Network or API error. |

On the Web Component build these events are dispatched through CustomEvent('yw:event', { detail }) with the widget event in detail.

Theming

Override the following CSS variables on the host element:

  • --yw-bg – primary surface background.
  • --yw-fg – text color.
  • --yw-accent – primary button color.

Example:

your-widget {
  --yw-bg: #0f172a;
  --yw-fg: #e2e8f0;
  --yw-accent: #38bdf8;
}

Search API integration

The widget calls POST https://gateway-prod.pxsol.com/v2/search with a public bearer token. Responses include booking_engine_url that is automatically opened when redirect is enabled. All requests are client-side, so ensure the provided token has the correct CORS permissions. Do not embed private keys or secrets in markup.

Security & CSP

  • Ship the ESM build and apply a CSP like script-src 'self' https://cdn.yourdomain.com so the widget loads from a trusted CDN.
  • Avoid unsafe-eval; the bundles are plain ESM/CJS/IIFE with no dynamic code execution.
  • When embedding in PCI-sensitive contexts, consider wrapping the Web Component in an iframe with a hardened sandbox attribute and communicate via postMessage.

Change log

See CHANGELOG.md for release notes.