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

@tebuto/react-booking-widget

v1.3.2

Published

React Component for the Tebuto Booking Widget

Downloads

405

Readme

Table of Contents

Features

  • Drop-in Widget - Embed the Tebuto booking widget with a single component
  • Custom Booking UIs - Build your own booking interface with powerful React hooks
  • Full TypeScript Support - Complete type definitions for all APIs
  • Theming - Customize colors, fonts, and styles to match your brand
  • React 19 Compatible - Built for the latest React version

Installation

# npm
npm install @tebuto/react-booking-widget

# pnpm
pnpm add @tebuto/react-booking-widget

# yarn
yarn add @tebuto/react-booking-widget

Requirements: React 19.0.0 or higher

Quick Start

The simplest way to add Tebuto booking to your site:

import { TebutoBookingWidget } from "@tebuto/react-booking-widget";

function BookingPage() {
  return <TebutoBookingWidget therapistUUID="your-therapist-uuid" />;
}

Note: You can obtain the therapist UUID from the appointment settings. In the embedding section, click on the HTML button and use the value from the data-therapist-uuid attribute.

Widget Configuration

Props Reference

| Prop | Type | Required | Default | Description | | ------------------ | ------------------- | -------- | --------------- | ------------------------------------------- | | therapistUUID | string | Yes | - | Unique identifier for the therapist | | backgroundColor | string | No | transparent | Background color (hex, rgb, etc.) | | border | boolean | No | true | Show border around the widget | | categories | number[] | No | [] | Filter appointments by category IDs | | includeSubusers | boolean | No | false | Include subuser appointments | | showQuickFilters | boolean | No | false | Show quick filter buttons for time slots | | inheritFont | boolean | No | false | Use parent page font instead of widget font | | theme | TebutoWidgetTheme | No | - | Theme customization object | | noScriptText | string | No | Default message | Text shown when JavaScript is disabled |

Theme Configuration

Customize the widget appearance with the theme prop:

import { TebutoBookingWidget } from "@tebuto/react-booking-widget";

function BookingPage() {
  return (
    <TebutoBookingWidget
      therapistUUID="your-uuid"
      theme={{
        primaryColor: "#10b981",
        backgroundColor: "#0f0f10",
        textPrimary: "#fafafa",
        textSecondary: "#a1a1aa",
        borderColor: "#2d2d30",
        fontFamily: '"Inter", sans-serif',
        inheritFont: false,
      }}
    />
  );
}

| Theme Property | Type | Description | | ----------------- | --------- | ------------------------------------------- | | primaryColor | string | Primary brand color for buttons, highlights | | backgroundColor | string | Main widget background | | textPrimary | string | Primary text color | | textSecondary | string | Secondary/muted text color | | borderColor | string | Border color | | fontFamily | string | Font family for the widget | | inheritFont | boolean | Inherit font from parent page |

Building Custom Booking UIs

For complete control over your booking interface, use the provided hooks to build a custom implementation.

TebutoProvider

Wrap your booking components with TebutoProvider to share configuration:

import { TebutoProvider } from "@tebuto/react-booking-widget";

function App() {
  return (
    <TebutoProvider
      therapistUUID="your-uuid"
      categories={[1, 2, 3]}
      includeSubusers={false}
    >
      <YourCustomBookingUI />
    </TebutoProvider>
  );
}

| Prop | Type | Required | Description | | ----------------- | ---------- | -------- | -------------------- | | therapistUUID | string | Yes | Therapist identifier | | apiBaseUrl | string | No | Custom API base URL | | categories | number[] | No | Category filter | | includeSubusers | boolean | No | Include subusers |

useBookingFlow Hook

The useBookingFlow hook provides complete booking flow orchestration:

import { TebutoProvider, useBookingFlow } from "@tebuto/react-booking-widget";

function BookingUI() {
  const {
    step,
    goToStep,
    therapist,
    slots,
    selectedDate,
    selectDate,
    selectedDateSlots,
    selectedSlot,
    selectSlot,
    selectedLocation,
    setLocation,
    submitBooking,
    booking,
    reset,
    isLoading,
    error,
  } = useBookingFlow({
    onBookingComplete: (booking) => console.log("Booked!", booking),
    onError: (error) => console.error("Error:", error),
  });

  switch (step) {
    case "loading":
      return <LoadingSpinner />;

    case "date-selection":
      return (
        <DatePicker
          availableDates={slots.availableDates}
          onSelect={selectDate}
        />
      );

    case "time-selection":
      return <TimeSlotPicker slots={selectedDateSlots} onSelect={selectSlot} />;

    case "booking-form":
      return <BookingForm onSubmit={submitBooking} isLoading={isLoading} />;

    case "confirmation":
      return (
        <Confirmation
          booking={booking.booking}
          onDownloadCalendar={booking.downloadCalendar}
          onReset={reset}
        />
      );

    case "error":
      return <ErrorDisplay error={error} onRetry={reset} />;
  }
}

function App() {
  return (
    <TebutoProvider therapistUUID="your-uuid">
      <BookingUI />
    </TebutoProvider>
  );
}

Individual Hooks

For fine-grained control, use the individual hooks:

useTherapist

Fetch therapist information:

const { data, isLoading, error, refetch } = useTherapist();
// data: { name, firstName, lastName, address, showWatermark }

useAvailableSlots

Fetch and manage available time slots:

const {
  slots, // All available slots
  slotsByDate, // Slots grouped by date
  availableDates, // Array of dates with availability
  getSlotsForDate, // Get slots for a specific date
  isLoading,
  error,
  refetch,
} = useAvailableSlots({ categories: [1, 2] });

useClaimSlot

Claim (reserve) a time slot before booking:

const {
  claim, // Claim a slot
  unclaim, // Release claimed slot
  claimData, // Claim response data
  isLoading,
  error,
} = useClaimSlot();

// Claim a slot
const response = await claim(selectedSlot);
// response: { isAvailable, requirePhoneNumber, requireAddress }

useBookAppointment

Complete the booking:

const {
  book, // Submit booking
  booking, // Booking response
  downloadCalendar, // Download ICS file
  reset, // Reset state
  isLoading,
  error,
} = useBookAppointment();

// Book appointment
const result = await book({
  slot: selectedSlot,
  client: {
    firstName: "Max",
    lastName: "Mustermann",
    email: "[email protected]",
    phone: "+49123456789", // optional
    notes: "First appointment", // optional
  },
  locationSelection: "onsite", // 'virtual' | 'onsite' | 'not-fixed'
});

Custom Booking Example

The library includes a full example implementation:

import { CustomBookingExample } from "@tebuto/react-booking-widget";

function BookingPage() {
  return <CustomBookingExample therapistUUID="your-uuid" categories={[1, 2]} />;
}

API Types

All types are exported for TypeScript users:

import type {
  // Configuration
  TebutoBookingWidgetConfiguration,
  TebutoWidgetTheme,

  // API Data
  Therapist,
  TimeSlot,
  EnrichedTimeSlot,
  ClaimResponse,
  BookingRequest,
  BookingResponse,
  ClientInfo,

  // Utilities
  AppointmentLocation, // 'virtual' | 'onsite' | 'not-fixed'
  Address,
  SlotsByDate,
  AsyncState,
} from "@tebuto/react-booking-widget";

License

MIT