@swift-food-services/catering-widget 0.1.0-beta.7 → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arnav Vaish
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -40,7 +40,8 @@ Defaults: Swift-hosted backend, `localStorage` persistence, neutral theme.
40
40
  | `publishableKey` | `string` | yes | Your `pk_live_...` key from Swift. |
41
41
  | `googleMapsApiKey` | `string` | yes | Google Maps JavaScript API key with the Places library enabled. Used by the address-autocomplete field. |
42
42
  | `theme` | `Theme` | no | Primary color, border radius, and font overrides. |
43
- | `initialData` | `InitialData` | no | Pre-populate event, address, and contact fields. Applied only on first mount. |
43
+ | `initialData` | `InitialData` | no | Pre-populate event window, address, and contact fields. Re-applied when its fingerprint changes between mounts; preserved on reload. See [Pre-filling known event details](#pre-filling-known-event-details). |
44
+ | `allowedCateringTimes` | `AllowedCateringTimes` | no | Partner-level catering availability window (`{ start: "HH:MM", end: "HH:MM" }`). Restricts the session delivery-time picker to slots within this range. |
44
45
  | `stickyTopOffset` | `number` | no | Pixels to offset the widget's internal sticky date/session nav from the top of the viewport. Set this to the height of any sticky/fixed navbar in your host layout so the widget's nav doesn't slide underneath it. Defaults to `0`. |
45
46
  | `onReady` | `() => void` | no | Fires when the widget has initialized. |
46
47
  | `onOrderComplete` | `(result: OrderCompleteResult) => void` | no | Fires after a successful order submission. See [`onOrderComplete` behaviour](#onordercompleteresult) for the timing. |
@@ -90,8 +91,10 @@ export default function Page() {
90
91
  publishableKey="pk_live_..."
91
92
  initialData={{
92
93
  eventName: "Alice's Birthday",
93
- eventDate: "2026-07-12",
94
- eventTime: "19:00",
94
+ eventStartDate: "2026-07-12",
95
+ eventStartTime: "18:00",
96
+ eventEndDate: "2026-07-12",
97
+ eventEndTime: "22:00",
95
98
  guestCount: 40,
96
99
  deliveryAddress: {
97
100
  line1: "1 Example Lane",
@@ -106,9 +109,32 @@ export default function Page() {
106
109
  />
107
110
  ```
108
111
 
109
- Every field in `initialData` is optional. Fields remain editable after pre-fill. `initialData` is only applied on first mount — if the user has a half-finished order in progress (persisted in `localStorage`), the persisted state wins.
112
+ Every field in `initialData` is optional. Fields remain editable after pre-fill.
110
113
 
111
- **Address requires `lat` and `lng`.** Delivery pricing depends on coordinates, so if you pass a `deliveryAddress` without both `lat` and `lng`, the widget ignores the entire address (no fields are pre-filled) and the guest is asked to pick one via the address-autocomplete field instead. The other `initialData` fields (event date/time, guest count, contact) still apply.
114
+ **How `initialData` interacts with persisted in-progress orders:** the widget fingerprints the supplied `initialData` (event window, guest count, address, and contact fields) and stores the fingerprint alongside the order. On every mount it compares the incoming fingerprint to the stored one:
115
+
116
+ - **Match** (e.g. page reload) → the in-progress order is preserved; `initialData` is _not_ re-applied.
117
+ - **Differ** (e.g. customer navigated back to your booking page, edited details, then returned) → the stored order is cleared and `initialData` is applied fresh.
118
+ - **No fingerprint stored yet** (first visit) → `initialData` is applied and the fingerprint is recorded.
119
+
120
+ For this to behave predictably, make sure the values you pass for the same booking are stable across renders — avoid recomputing dynamic values like `new Date()` inline in render.
121
+
122
+ The event window is a start–end pair (`eventStartDate` + `eventStartTime` to `eventEndDate` + `eventEndTime`). When set, the session editor restricts session dates to that range and filters the delivery-time picker so it stays within the window on the boundary days.
123
+
124
+ **Address requires `lat` and `lng`.** Delivery pricing depends on coordinates, so if you pass a `deliveryAddress` without both `lat` and `lng`, the widget ignores the entire address (no fields are pre-filled) and the guest is asked to pick one via the address-autocomplete field instead. The other `initialData` fields (event window, guest count, contact) still apply.
125
+
126
+ ### Restricting catering hours (`allowedCateringTimes`)
127
+
128
+ Pass a partner-level catering availability window to restrict the session delivery-time picker to a subset of the day. Times are 24-hour `"HH:MM"` strings.
129
+
130
+ ```tsx
131
+ <CateringWidget
132
+ publishableKey="pk_live_..."
133
+ allowedCateringTimes={{ start: "09:00", end: "19:00" }}
134
+ />
135
+ ```
136
+
137
+ Each slot is a 30-minute window. A slot is shown only if it fits entirely within `[start, end]` — its start must be ≥ `start` and its end must be ≤ `end`. With `end: "19:00"`, for example, the latest visible slot is 6:30 PM – 7:00 PM. If `initialData` also defines an event window, the two filters compose: the partner window is the outer bound, and the event start/end further narrow the picker on boundary days.
112
138
 
113
139
  ### Offsetting below a host navbar
114
140
 
@@ -131,6 +157,7 @@ import {
131
157
  type CateringWidgetProps,
132
158
  type Theme,
133
159
  type InitialData,
160
+ type AllowedCateringTimes,
134
161
  type OrderCompleteResult,
135
162
  type OrderSummary,
136
163
  type MealSession,