@arkipay/booking-widget 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -0
- package/dist/index.cjs +1721 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +521 -0
- package/dist/index.d.ts +521 -0
- package/dist/index.js +1686 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +289 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# @arkipay/booking-widget
|
|
2
|
+
|
|
3
|
+
Embeddable React booking widget for the ArkiPay / EasyAppts appointment platform. Drop
|
|
4
|
+
`<BookingProvider>` + `<BookingWidget>` into any React app and your customers can book
|
|
5
|
+
appointments against your tenant — service → provider → date/time → details → confirmation,
|
|
6
|
+
including the online-payment redirect. The widget **inherits your site's theme** automatically.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @arkipay/booking-widget
|
|
12
|
+
# or: pnpm add @arkipay/booking-widget
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`react` and `react-dom` (v18.3+ or v19) are peer dependencies you already have.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { BookingProvider, BookingWidget } from "@arkipay/booking-widget";
|
|
21
|
+
import "@arkipay/booking-widget/styles.css";
|
|
22
|
+
|
|
23
|
+
export default function BookingPage() {
|
|
24
|
+
return (
|
|
25
|
+
<BookingProvider publishableKey="pk_live_xxx">
|
|
26
|
+
<BookingWidget />
|
|
27
|
+
</BookingProvider>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Use your **publishable** key (`pk_live_…` / `pk_test_…`) — never a secret key. The widget talks
|
|
33
|
+
only to the public API, so the key is safe to ship in browser code.
|
|
34
|
+
|
|
35
|
+
### Next.js App Router
|
|
36
|
+
|
|
37
|
+
The package ships with a `"use client"` directive, so you can import it directly into a Server
|
|
38
|
+
Component — no wrapper needed.
|
|
39
|
+
|
|
40
|
+
## Theming
|
|
41
|
+
|
|
42
|
+
The widget is fully tokenised. Every visual value resolves in this order (highest wins):
|
|
43
|
+
|
|
44
|
+
1. an explicit `theme` prop on `<BookingProvider>`
|
|
45
|
+
2. **your site's own CSS design-system token** (e.g. `--brand`, `--fg`) — inherited automatically
|
|
46
|
+
3. tenant config (brand colour, configured in the platform)
|
|
47
|
+
4. a built-in default
|
|
48
|
+
|
|
49
|
+
### Inherit your site's theme (zero config)
|
|
50
|
+
|
|
51
|
+
If your site already defines any of these CSS variables on an ancestor element, the widget picks
|
|
52
|
+
them up with no props at all:
|
|
53
|
+
|
|
54
|
+
| Host token | Controls | Widget token |
|
|
55
|
+
| ----------------- | -------------------------------- | -------------- |
|
|
56
|
+
| `--brand` / `--accent` | Primary / call-to-action colour | `--ea-brand` |
|
|
57
|
+
| `--fg` | Body text | `--ea-text` |
|
|
58
|
+
| `--fg-muted` | Secondary / hint text | `--ea-muted` |
|
|
59
|
+
| `--border` | Card & input borders | `--ea-border` |
|
|
60
|
+
| `--bg-elevated` | Card / input / surface background | `--ea-surface` |
|
|
61
|
+
| `--danger` | Error / validation colour | `--ea-error` |
|
|
62
|
+
| `--radius-md` | Corner radius | `--ea-radius` |
|
|
63
|
+
| `--font-sans` | Font stack | `--ea-font` |
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
// Your app already sets these on :root or a wrapper — the widget just follows.
|
|
67
|
+
<div style={{ "--brand": "#ff6b35", "--font-sans": "Inter, sans-serif" }}>
|
|
68
|
+
<BookingProvider publishableKey="pk_live_xxx">
|
|
69
|
+
<BookingWidget />
|
|
70
|
+
</BookingProvider>
|
|
71
|
+
</div>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Explicit `theme` prop
|
|
75
|
+
|
|
76
|
+
For one-off overrides without a design system:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<BookingProvider
|
|
80
|
+
publishableKey="pk_live_xxx"
|
|
81
|
+
theme={{
|
|
82
|
+
brandColor: "#0f6b8c",
|
|
83
|
+
fontFamily: "Geist, system-ui, sans-serif",
|
|
84
|
+
borderRadius: "12px",
|
|
85
|
+
colorScheme: "system", // "light" | "dark" | "system"
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<BookingWidget />
|
|
89
|
+
</BookingProvider>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Full `theme` surface: `brandColor`, `onBrandColor`, `textColor`, `mutedColor`, `borderColor`,
|
|
93
|
+
`surfaceColor`, `errorColor`, `borderRadius`, `fontFamily`, `maxWidth`, `colorScheme`.
|
|
94
|
+
|
|
95
|
+
### Dark mode
|
|
96
|
+
|
|
97
|
+
Pass `theme={{ colorScheme: "dark" }}` (or `"system"` to follow `prefers-color-scheme`). If your
|
|
98
|
+
host already flips its own `--fg` / `--bg-elevated` tokens, the widget follows those instead — no
|
|
99
|
+
extra config needed.
|
|
100
|
+
|
|
101
|
+
### Override via plain CSS
|
|
102
|
+
|
|
103
|
+
Because every element is scoped under `.ea-booking-widget`, you can override any token from your
|
|
104
|
+
own stylesheet without collisions:
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
.ea-booking-widget {
|
|
108
|
+
--ea-radius: 4px;
|
|
109
|
+
}
|
|
110
|
+
.ea-booking-widget .ea-btn-primary {
|
|
111
|
+
font-weight: 600;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## `BookingProvider` props
|
|
116
|
+
|
|
117
|
+
| Prop | Type | Default | Notes |
|
|
118
|
+
| ------------------ | -------------------------------------- | --------------------------- | ----- |
|
|
119
|
+
| `publishableKey` | `string` | — | Required. `pk_live_…` / `pk_test_…` |
|
|
120
|
+
| `apiUrl` | `string` | `https://api.easyappts.com` | Override for self-hosted / sandbox |
|
|
121
|
+
| `theme` | `BookingTheme` | `{}` | See Theming |
|
|
122
|
+
| `locale` | `string` | tenant default | e.g. `"en"` |
|
|
123
|
+
| `onBooked` | `(appointment) => void` | — | Fires on successful booking |
|
|
124
|
+
| `initialServiceId` / `initialProviderId` | `string` | URL `?service=`/`?provider=` | Pre-select a step |
|
|
125
|
+
| `className` / `style` | `string` / `CSSProperties` | — | Applied to the widget root |
|
|
126
|
+
| `botProtection` | `boolean` | `true` | See below |
|
|
127
|
+
|
|
128
|
+
### Bot protection
|
|
129
|
+
|
|
130
|
+
The widget uses [Vercel BotID](https://vercel.com/docs/botid) on the booking request. Full
|
|
131
|
+
protection requires the Vercel BotID proxy on your host. If you're **not** on Vercel, set
|
|
132
|
+
`botProtection={false}` — the API's server-side rate limiter remains the backstop.
|
|
133
|
+
|
|
134
|
+
## Composing your own flow
|
|
135
|
+
|
|
136
|
+
Prefer your own layout? Import the step components and drive them with `useBooking()`:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import {
|
|
140
|
+
BookingProvider, ServicePicker, ProviderPicker, DatePicker,
|
|
141
|
+
TimeSlotPicker, CustomerForm, ConfirmStep, BookedSummary, useBooking,
|
|
142
|
+
} from "@arkipay/booking-widget";
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
A non-React / server integration can use the bundled API client directly:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { createBookingClient } from "@arkipay/booking-widget";
|
|
149
|
+
const client = createBookingClient({ publishableKey: "pk_live_xxx" });
|
|
150
|
+
const config = await client.getTenantConfig();
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
UNLICENSED — for use by ArkiPay customers integrating the booking platform.
|