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

@openings-link/react-ui

v0.3.3

Published

Themed, drop-in React booking widget for Openings. Styled with CSS custom properties.

Readme

@openings-link/react-ui

Themed, drop-in React booking widget for the Openings platform.

Built on @openings-link/react (headless core). Styled with CSS custom properties — no Tailwind, no CSS modules.

Install

npm install @openings-link/react @openings-link/react-ui

Quick Start

import { BookingWidget } from "@openings-link/react-ui";

function App() {
  return (
    <BookingWidget
      business="your-business-handle"
      theme={{ accent: "#8B5CF6" }}
      on={{
        onBookingComplete: (result) => {
          console.log("Booked!", result);
        },
      }}
    />
  );
}

CORS and apiBase

BookingWidget defaults to apiBase="https://api.openings.link".

If your frontend runs on a third-party domain, prefer a same-origin proxy route in your app and point the widget to that proxy:

<BookingWidget business="your-business-handle" apiBase="/api/openings" />

This is the recommended setup for npm users to avoid browser CORS issues.

Full proxy templates: https://github.com/openings-link/openings-react/blob/main/docs/proxy-templates.md

Props

| Prop | Type | Description | | ----------------------- | ---------------------------- | ------------------------------------------------------ | | business* | string | Business handle (slug). Required. | | apiBase | string | API base URL. Defaults to https://api.openings.link. | | scheduleId | string | Pre-select a schedule (skip location picker). | | memberId | string | Pre-select a staff member (show their availability). | | theme | BookingTheme | Accent color, border radius, font, light/dark mode. | | labels | Partial<BookingLabels> | Override any user-facing string for i18n. | | features | BookingFeatures | Optional capabilities, such as rescheduling. | | completionMode | "inline" \| "external" | Use external to handle confirmation in the host app. | | apiClient | ApiClient | Custom API client for testing or mock data. | | appointmentMetadata | Record<string, string> | Extra metadata stored on created appointments. | | on | OpeningsCallbacks | Event callbacks for booking lifecycle. | | onConsultationRequest | (member, services) => void | Custom handler for consultation services. | | className | string | CSS class for the root container. |

Appointments created through the widget automatically include source: "openings-react" metadata. Use appointmentMetadata for additional string fields such as an integration or campaign id.

Custom Confirmation

By default, the widget shows its built-in confirmation scene after an appointment is created. Use completionMode="external" when the host app should own the confirmation page or modal:

<BookingWidget
  business="your-business-handle"
  completionMode="external"
  on={{
    onBookingComplete: (result) => {
      router.push(`/appointments/${result.appointmentId}/confirmed`);
    },
  }}
/>

onBookingComplete still fires as soon as appointment creation succeeds. In external mode, the widget shows a brief completed state instead of rendering the built-in confirmation scene while the host app handles navigation or opens a custom modal.

Optional Rescheduling

Rescheduling is disabled by default. Enable it when you want returning customers with upcoming appointments to choose between booking a new appointment and rescheduling an existing one:

<BookingWidget
  business="your-business-handle"
  features={{ rescheduling: true }}
  on={{
    onRescheduleComplete: (result) => {
      console.log("Rescheduled!", result);
    },
  }}
/>

The widget only shows appointment details after the customer verifies with the reschedule lookup code returned by the Openings API.

Theme

{
  accent?: string;      // Primary color (default: "#000000")
  radius?: number;      // Border radius in px (default: 8)
  fontFamily?: string;  // Font family (default: system)
  mode?: "light" | "dark" | "auto";
}

All CSS custom properties are prefixed --openings-*.

Live Demo

react.openings.link

License

MIT