@zappie/foundations 0.6.0 → 0.7.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/CHANGELOG.md +15 -0
- package/dist/fulfilment/schedule.js +22 -6
- package/dist/fulfilment/schedule.js.map +1 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @zappie/foundations
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4f55e71: `Schedule` tells loading and failed hours apart from a closed branch. While the branch's menu hours load or after they fail, `days` and `slots` are empty and `canAsap` is false, which looked the same as a closed branch, so a site could say the branch wasn't taking orders while it was open.
|
|
8
|
+
|
|
9
|
+
`ScheduleState` adds `status` (`"loading"`, `"error"` or `"ready"`), `retry()`, which loads the hours again after an error, and `isClosed`, true only when the hours are known and nothing can be ordered. Show a loading or error state until `status` is `"ready"`, and say the branch is closed only when `isClosed` is true. The `Schedule` element adds `data-status`, sets `aria-busy` while loading and sets `data-invalid` only once the hours are known. `ScheduleStatus` is exported.
|
|
10
|
+
|
|
11
|
+
The kit's and the starter's schedule picker (registry item `schedule-picker` 1.1.0, which requires `@zappie/foundations` ^0.7.0) show "Checking opening hours…" while loading, "Couldn’t load opening hours." with a "Try again" button after an error, and "<branch> isn’t taking orders right now." when the branch is closed.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [97d7e6a]
|
|
16
|
+
- @zappie/sdk@0.7.0
|
|
17
|
+
|
|
3
18
|
## 0.6.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/fulfilment/schedule.tsx
|
|
4
|
-
import { useMenu, useStore } from "@zappie/sdk/react";
|
|
4
|
+
import { useMenu, useStore, useZappie } from "@zappie/sdk/react";
|
|
5
5
|
import { forwardRef, useEffect, useMemo, useState } from "react";
|
|
6
6
|
import { part } from "../internal/slot.js";
|
|
7
7
|
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
@@ -82,8 +82,12 @@ var Schedule = forwardRef(function Schedule2({
|
|
|
82
82
|
noticeMinutes,
|
|
83
83
|
...props
|
|
84
84
|
}, ref) {
|
|
85
|
+
const client = useZappie();
|
|
85
86
|
const store = useStore();
|
|
86
87
|
const menu = useMenu(branch.id, { metadataOnly: true });
|
|
88
|
+
const [retrying, setRetrying] = useState(false);
|
|
89
|
+
const status = menu.isLoading || retrying ? "loading" : menu.error ? "error" : "ready";
|
|
90
|
+
const ready = status === "ready";
|
|
87
91
|
const timezone = suppliedTimezone ?? branch.timezone ?? store.data?.timezone ?? "UTC";
|
|
88
92
|
const [now, setNow] = useState(() => /* @__PURE__ */ new Date());
|
|
89
93
|
useEffect(() => {
|
|
@@ -99,7 +103,7 @@ var Schedule = forwardRef(function Schedule2({
|
|
|
99
103
|
onChange: onValueChange
|
|
100
104
|
});
|
|
101
105
|
const slots = useMemo(
|
|
102
|
-
() =>
|
|
106
|
+
() => !ready ? [] : scheduleSlots(branch, timezone, now, {
|
|
103
107
|
intervalMinutes,
|
|
104
108
|
maxDays,
|
|
105
109
|
noticeMinutes,
|
|
@@ -113,15 +117,22 @@ var Schedule = forwardRef(function Schedule2({
|
|
|
113
117
|
maxDays,
|
|
114
118
|
noticeMinutes,
|
|
115
119
|
menu.data?.schedule,
|
|
116
|
-
|
|
117
|
-
menu.error
|
|
120
|
+
ready
|
|
118
121
|
]
|
|
119
122
|
);
|
|
120
123
|
const days = Array.from(new Set(slots.map((slot) => slot.date))).map(
|
|
121
124
|
(date) => ({ date, slots: slots.filter((slot) => slot.date === date) })
|
|
122
125
|
);
|
|
123
|
-
const canAsap =
|
|
126
|
+
const canAsap = ready && !menu.data?.schedule?.preorder && getOpenStatus(branch, timezone, now).isOpen;
|
|
124
127
|
const isValid = selection === null ? canAsap : slots.some((slot) => slot.value === selection);
|
|
128
|
+
const retry = () => {
|
|
129
|
+
if (retrying || !menu.error) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
setRetrying(true);
|
|
133
|
+
void client.menu.get({ branch: branch.id, metadataOnly: true }).catch(() => {
|
|
134
|
+
}).finally(() => setRetrying(false));
|
|
135
|
+
};
|
|
125
136
|
const setValue = (next) => {
|
|
126
137
|
if (next === null ? canAsap : slots.some((slot) => slot.value === next)) {
|
|
127
138
|
setSelection(next);
|
|
@@ -131,6 +142,9 @@ var Schedule = forwardRef(function Schedule2({
|
|
|
131
142
|
"div",
|
|
132
143
|
props,
|
|
133
144
|
{
|
|
145
|
+
status,
|
|
146
|
+
retry,
|
|
147
|
+
isClosed: ready && !canAsap && slots.length === 0,
|
|
134
148
|
days,
|
|
135
149
|
slots,
|
|
136
150
|
value: selection,
|
|
@@ -141,8 +155,10 @@ var Schedule = forwardRef(function Schedule2({
|
|
|
141
155
|
},
|
|
142
156
|
{
|
|
143
157
|
role: "group",
|
|
158
|
+
"aria-busy": status === "loading" ? true : void 0,
|
|
159
|
+
"data-status": status,
|
|
144
160
|
"data-state": isValid ? "valid" : "invalid",
|
|
145
|
-
"data-invalid": isValid ? void 0 : ""
|
|
161
|
+
"data-invalid": isValid || !ready ? void 0 : ""
|
|
146
162
|
},
|
|
147
163
|
ref
|
|
148
164
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/fulfilment/schedule.tsx"],
|
|
4
|
-
"mappings": ";;;AAEA,SAAS,SAAS,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["Schedule"]
|
|
6
6
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -517,10 +517,25 @@ type ScheduleSlot = {
|
|
|
517
517
|
label: string;
|
|
518
518
|
date: string;
|
|
519
519
|
};
|
|
520
|
+
/**
|
|
521
|
+
* Whether the branch's menu hours have loaded. `loading` and `error` say nothing about whether the
|
|
522
|
+
* branch is open.
|
|
523
|
+
*/
|
|
524
|
+
type ScheduleStatus = "loading" | "error" | "ready";
|
|
520
525
|
/**
|
|
521
526
|
* Available days and slots, the selected time and controls for choosing ASAP or a scheduled time.
|
|
527
|
+
*
|
|
528
|
+
* Read `status` first. Until it is `ready`, `days` and `slots` are empty and `canAsap` is false
|
|
529
|
+
* because the hours haven't loaded yet. Show a loading or error state then. Telling the shopper
|
|
530
|
+
* the branch is closed is only right when `isClosed` is true.
|
|
522
531
|
*/
|
|
523
532
|
type ScheduleState = {
|
|
533
|
+
/** `loading` while the menu hours load, `error` when they failed, and `ready` once they're known. */
|
|
534
|
+
status: ScheduleStatus;
|
|
535
|
+
/** Load the menu hours again after an error. */
|
|
536
|
+
retry: () => void;
|
|
537
|
+
/** True when the hours are known and the branch takes neither ASAP nor scheduled orders. */
|
|
538
|
+
isClosed: boolean;
|
|
524
539
|
days: {
|
|
525
540
|
date: string;
|
|
526
541
|
slots: ScheduleSlot[];
|
|
@@ -529,6 +544,7 @@ type ScheduleState = {
|
|
|
529
544
|
value: string | null;
|
|
530
545
|
setValue: (value: string | null) => void;
|
|
531
546
|
isAsap: boolean;
|
|
547
|
+
/** True when the hours are known and the branch takes an order now. */
|
|
532
548
|
canAsap: boolean;
|
|
533
549
|
isValid: boolean;
|
|
534
550
|
};
|
|
@@ -552,6 +568,7 @@ declare function scheduleSlots(branch: Branch$1, timezone: string, now: Date, {
|
|
|
552
568
|
/**
|
|
553
569
|
* Expose valid fulfilment slots and ASAP eligibility using branch hours and loaded menu metadata.
|
|
554
570
|
* Use null for ASAP. Requires a ZappieProvider and refreshes the available times each minute.
|
|
571
|
+
* While the menu hours load or after they fail, `status` says so. Don't show those states as closed.
|
|
555
572
|
*/
|
|
556
573
|
declare const Schedule: react.ForwardRefExoticComponent<Omit<react.AllHTMLAttributes<HTMLElement>, PartOwnedAttributes> & {
|
|
557
574
|
asChild?: boolean;
|
|
@@ -1104,4 +1121,4 @@ declare const OpenStatus: react.ForwardRefExoticComponent<Omit<react.AllHTMLAttr
|
|
|
1104
1121
|
declare const FOUNDATIONS_VERSION: string;
|
|
1105
1122
|
|
|
1106
1123
|
export { Account, AccountNotConfiguredError, Address, Branch, BranchMap, Cart, Choice, DeliveryMap, FOUNDATIONS_VERSION, Fulfilment, Image, ItemForm, Money, OpenStatus, OptionGroup, Otp, Overlay, PartProps, PaymentMethods, Quantity, Schedule, Search, Totals, ZappieAccountLink, canOrderAhead, contactLinks, createSearchIndex, deferred, formatOpeningHours, formatWallClock, getOpenStatus, parseWallClock, scheduleSlots, useControllableState, useIntentPreload, useOverlay, useZappieAccountUrl, zappieAccountUrl, zappieEnvironment, zappieSupportUrl };
|
|
1107
|
-
export type { ActiveGroup, AddressState, AddressSuggestion, BranchMapLoadErrorState, BranchMapProps, ContactLink, Customer, Deferred, DeferredIdleOptions, DeferredProps, DeliveryMapProps, ImageProps, IntentPreloadHandlers, ItemFormContext, ItemFormInvalidGroup, ItemFormProps, MapLoadErrorState, PaymentMethod, QuantityProps, QuantityState, ScheduleSlot, ScheduleState, SearchResult, SearchSource, SearchState, SignInOptions, TotalsState, ZappieSupportContext };
|
|
1124
|
+
export type { ActiveGroup, AddressState, AddressSuggestion, BranchMapLoadErrorState, BranchMapProps, ContactLink, Customer, Deferred, DeferredIdleOptions, DeferredProps, DeliveryMapProps, ImageProps, IntentPreloadHandlers, ItemFormContext, ItemFormInvalidGroup, ItemFormProps, MapLoadErrorState, PaymentMethod, QuantityProps, QuantityState, ScheduleSlot, ScheduleState, ScheduleStatus, SearchResult, SearchSource, SearchState, SignInOptions, TotalsState, ZappieSupportContext };
|
package/dist/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"mappings": ";;;AACA,SAAS,uBAAuB;AAIhC,SAAS,SAAS,iCAAiC;AAEnD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,mBAAmB;AAOvC,SAAS,MAAM,cAAc;AAE7B,SAAS,UAAU,wBAAwB;AAO3C,SAAS,eAAe;AAKxB,SAAS,cAAc;AACvB,SAAS,UAAU,qBAAqB;
|
|
4
|
+
"mappings": ";;;AACA,SAAS,uBAAuB;AAIhC,SAAS,SAAS,iCAAiC;AAEnD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,mBAAmB;AAOvC,SAAS,MAAM,cAAc;AAE7B,SAAS,UAAU,wBAAwB;AAO3C,SAAS,eAAe;AAKxB,SAAS,cAAc;AACvB,SAAS,UAAU,qBAAqB;AAMxC,SAAS,kBAAkB;AAE3B,SAAS,4BAA4B;AACrC,cAAc;AACd,SAAS,aAAa;AAEtB,SAAS,aAAa;AACtB,SAAS,WAAW;AACpB,SAAS,SAAS,kBAAkB;AACpC,SAAS,sBAAsB;AAE/B,SAAS,mBAAmB,cAAc;AAE1C,SAAS,cAAc,wBAAwB;AAE/C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AA3DpB,IAAM,sBAA8B;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zappie/foundations",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "UI-less React primitives for Zappie storefronts: behaviour, state and accessibility without styles.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@base-ui/react": "^1.9.0",
|
|
35
35
|
"@googlemaps/markerclusterer": "^2.6.2",
|
|
36
|
-
"@zappie/sdk": "^0.
|
|
36
|
+
"@zappie/sdk": "^0.7.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"react": "^18.2.0 || ^19.0.0",
|