@zappie/theme-base 0.1.0 → 0.1.2

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.
Files changed (129) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +26 -53
  3. package/dist/address.js +99 -2
  4. package/dist/address.js.map +7 -1
  5. package/dist/cart/address-sheet.js +143 -0
  6. package/dist/cart/address-sheet.js.map +7 -0
  7. package/dist/cart/cart-issues.js +72 -0
  8. package/dist/cart/cart-issues.js.map +7 -0
  9. package/dist/cart/cart-line-groups.js +34 -0
  10. package/dist/cart/cart-line-groups.js.map +7 -0
  11. package/dist/{chunk-FB5DRCU7.js → cart/cart-line.js} +9 -70
  12. package/dist/cart/cart-line.js.map +7 -0
  13. package/dist/cart/cart-lines.js +27 -0
  14. package/dist/cart/cart-lines.js.map +7 -0
  15. package/dist/cart/cart-schedule.js +24 -0
  16. package/dist/cart/cart-schedule.js.map +7 -0
  17. package/dist/cart/cart-sheet.js +35 -0
  18. package/dist/cart/cart-sheet.js.map +7 -0
  19. package/dist/cart/checkout-cta.js +81 -0
  20. package/dist/cart/checkout-cta.js.map +7 -0
  21. package/dist/cart/checkout-state.js +74 -0
  22. package/dist/cart/checkout-state.js.map +7 -0
  23. package/dist/cart/clear-cart.js +44 -0
  24. package/dist/cart/clear-cart.js.map +7 -0
  25. package/dist/cart/customer-details.js +70 -0
  26. package/dist/cart/customer-details.js.map +7 -0
  27. package/dist/cart/delivery-distance.js +22 -0
  28. package/dist/cart/delivery-distance.js.map +7 -0
  29. package/dist/cart/empty-cart.js +14 -0
  30. package/dist/cart/empty-cart.js.map +7 -0
  31. package/dist/cart/fulfilment-panel.js +83 -0
  32. package/dist/cart/fulfilment-panel.js.map +7 -0
  33. package/dist/cart/line-editor.js +35 -0
  34. package/dist/cart/line-editor.js.map +7 -0
  35. package/dist/cart/line-options.js +96 -0
  36. package/dist/cart/line-options.js.map +7 -0
  37. package/dist/cart/loading.js +17 -0
  38. package/dist/cart/loading.js.map +7 -0
  39. package/dist/cart/promo-sheet.js +103 -0
  40. package/dist/cart/promo-sheet.js.map +7 -0
  41. package/dist/cart/region-picker.js +40 -0
  42. package/dist/cart/region-picker.js.map +7 -0
  43. package/dist/cart/rewards-sheet.js +86 -0
  44. package/dist/cart/rewards-sheet.js.map +7 -0
  45. package/dist/cart/schedule-sheet.js +87 -0
  46. package/dist/cart/schedule-sheet.js.map +7 -0
  47. package/dist/{chunk-JFEI2OUZ.js → cart/theme-class.js} +7 -5
  48. package/dist/cart/theme-class.js.map +7 -0
  49. package/dist/cart/totals.js +81 -0
  50. package/dist/cart/totals.js.map +7 -0
  51. package/dist/cart/use-address-selection.js +130 -0
  52. package/dist/cart/use-address-selection.js.map +7 -0
  53. package/dist/cart.js +21 -1069
  54. package/dist/cart.js.map +7 -1
  55. package/dist/catalogue/catalogue-cart.js +25 -0
  56. package/dist/catalogue/catalogue-cart.js.map +7 -0
  57. package/dist/catalogue/catalogue-header.js +88 -0
  58. package/dist/catalogue/catalogue-header.js.map +7 -0
  59. package/dist/catalogue/catalogue-pages.js +68 -0
  60. package/dist/catalogue/catalogue-pages.js.map +7 -0
  61. package/dist/catalogue/catalogue-search.js +89 -0
  62. package/dist/catalogue/catalogue-search.js.map +7 -0
  63. package/dist/catalogue/category-navigation.js +98 -0
  64. package/dist/catalogue/category-navigation.js.map +7 -0
  65. package/dist/catalogue/category-section.js +113 -0
  66. package/dist/catalogue/category-section.js.map +7 -0
  67. package/dist/catalogue/info-banners.js +148 -0
  68. package/dist/catalogue/info-banners.js.map +7 -0
  69. package/dist/catalogue/item-tile.js +55 -0
  70. package/dist/catalogue/item-tile.js.map +7 -0
  71. package/dist/catalogue/loader.js +136 -0
  72. package/dist/catalogue/loader.js.map +7 -0
  73. package/dist/{chunk-USSLDBDY.js → catalogue/presentation.js} +12 -9
  74. package/dist/catalogue/presentation.js.map +7 -0
  75. package/dist/catalogue/saved-catalogue-sync.js +115 -0
  76. package/dist/catalogue/saved-catalogue-sync.js.map +7 -0
  77. package/dist/catalogue/types.js +1 -0
  78. package/dist/catalogue/types.js.map +7 -0
  79. package/dist/catalogue/use-catalogue-data.js +88 -0
  80. package/dist/catalogue/use-catalogue-data.js.map +7 -0
  81. package/dist/catalogue/use-category-scroll.js +115 -0
  82. package/dist/catalogue/use-category-scroll.js.map +7 -0
  83. package/dist/catalogue/use-item-opener.js +46 -0
  84. package/dist/catalogue/use-item-opener.js.map +7 -0
  85. package/dist/catalogue/use-search-source.js +132 -0
  86. package/dist/catalogue/use-search-source.js.map +7 -0
  87. package/dist/catalogue.js +26 -1216
  88. package/dist/catalogue.js.map +7 -1
  89. package/dist/checkout.js +149 -2
  90. package/dist/checkout.js.map +7 -1
  91. package/dist/host-bridge.js +22 -2
  92. package/dist/host-bridge.js.map +7 -1
  93. package/dist/index.js +3 -3
  94. package/dist/index.js.map +7 -1
  95. package/dist/item/configurator-commit.js +15 -0
  96. package/dist/item/configurator-commit.js.map +7 -0
  97. package/dist/item/configurator-draft.js +63 -0
  98. package/dist/item/configurator-draft.js.map +7 -0
  99. package/dist/item/configurator.js +135 -0
  100. package/dist/item/configurator.js.map +7 -0
  101. package/dist/item/note.js +65 -0
  102. package/dist/item/note.js.map +7 -0
  103. package/dist/item/variant-status.js +23 -0
  104. package/dist/item/variant-status.js.map +7 -0
  105. package/dist/item-frame.js +60 -3
  106. package/dist/item-frame.js.map +7 -1
  107. package/dist/item.js +11 -11
  108. package/dist/item.js.map +7 -1
  109. package/dist/navigation.js +39 -2
  110. package/dist/navigation.js.map +7 -1
  111. package/dist/url-navigation-state.js +61 -0
  112. package/dist/url-navigation-state.js.map +7 -0
  113. package/dist/{chunk-ILOCSCZL.js → url-navigation.js} +12 -89
  114. package/dist/url-navigation.js.map +7 -0
  115. package/package.json +8 -7
  116. package/dist/chunk-2MV6KU3R.js +0 -352
  117. package/dist/chunk-2MV6KU3R.js.map +0 -1
  118. package/dist/chunk-FB5DRCU7.js.map +0 -1
  119. package/dist/chunk-IG63ONID.js +0 -139
  120. package/dist/chunk-IG63ONID.js.map +0 -1
  121. package/dist/chunk-ILOCSCZL.js.map +0 -1
  122. package/dist/chunk-JFEI2OUZ.js.map +0 -1
  123. package/dist/chunk-NTJONY3N.js +0 -95
  124. package/dist/chunk-NTJONY3N.js.map +0 -1
  125. package/dist/chunk-QWST2TA2.js +0 -22
  126. package/dist/chunk-QWST2TA2.js.map +0 -1
  127. package/dist/chunk-USSLDBDY.js.map +0 -1
  128. package/dist/chunk-VIAJ27YC.js +0 -59
  129. package/dist/chunk-VIAJ27YC.js.map +0 -1
@@ -0,0 +1,135 @@
1
+ "use client";
2
+
3
+ // src/item/configurator.tsx
4
+ import { ItemForm, Money, Quantity } from "@zappie/foundations";
5
+ import { useZappie } from "@zappie/sdk/react";
6
+ import { countEvent } from "@zappie/sdk/visits";
7
+ import { Fragment, useState } from "react";
8
+ import { LineOptions } from "../cart/line-options.js";
9
+ import { createConfiguratorCommit } from "./configurator-commit.js";
10
+ import { useConfiguratorDraft } from "./configurator-draft.js";
11
+ import { ItemNote } from "./note.js";
12
+ import { VariantStatus } from "./variant-status.js";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ function ItemConfigurator({
15
+ item,
16
+ menuId,
17
+ line,
18
+ onComplete,
19
+ scope,
20
+ showPrice = false,
21
+ introduction
22
+ }) {
23
+ const client = useZappie();
24
+ const { clear, restored, setValue, value } = useConfiguratorDraft({
25
+ item,
26
+ ...menuId !== void 0 ? { menuId } : {},
27
+ ...line !== void 0 ? { line } : {},
28
+ scope
29
+ });
30
+ const [error, setError] = useState();
31
+ const onCommit = createConfiguratorCommit(client, line);
32
+ return /* @__PURE__ */ jsx(
33
+ ItemForm.Root,
34
+ {
35
+ item,
36
+ value,
37
+ onValueChange: (next) => {
38
+ const nextValue = { ...next };
39
+ delete nextValue.variantId;
40
+ setValue(nextValue);
41
+ setError(void 0);
42
+ },
43
+ ...onCommit ? { onCommit } : {},
44
+ onAdded: () => {
45
+ if (!line) {
46
+ countEvent("add");
47
+ }
48
+ clear();
49
+ onComplete();
50
+ },
51
+ className: "z-base-configurator",
52
+ children: (configuration) => /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ /* @__PURE__ */ jsxs("div", { className: "z-base-item-summary", children: [
54
+ showPrice && /* @__PURE__ */ jsxs("p", { className: "z-base-item-price", children: [
55
+ /* @__PURE__ */ jsx(Money, { value: configuration.unitPrice }),
56
+ item.compareAtPrice && /* @__PURE__ */ jsx("del", { children: /* @__PURE__ */ jsx(Money, { value: item.compareAtPrice }) })
57
+ ] }),
58
+ !line && /* @__PURE__ */ jsx(
59
+ ItemNote,
60
+ {
61
+ id: item.id,
62
+ value: value.note ?? "",
63
+ onChange: (note) => configuration.setValue({ ...value, note })
64
+ }
65
+ )
66
+ ] }),
67
+ line && /* @__PURE__ */ jsxs("label", { className: "z-base-field", children: [
68
+ "Note",
69
+ /* @__PURE__ */ jsx(
70
+ "textarea",
71
+ {
72
+ className: "z-base-input",
73
+ maxLength: line ? 280 : Math.max(35, value.note?.length ?? 0),
74
+ value: value.note ?? "",
75
+ onChange: (event) => configuration.setValue({ ...value, note: event.target.value })
76
+ }
77
+ )
78
+ ] }),
79
+ showPrice && /* @__PURE__ */ jsx(VariantStatus, { item, value: configuration.value }),
80
+ introduction,
81
+ /* @__PURE__ */ jsx(LineOptions, {}),
82
+ configuration.issues.length > 0 && /* @__PURE__ */ jsx("div", { role: "alert", children: configuration.issues.map((issue, index) => /* @__PURE__ */ jsx("p", { children: issue.message }, `${issue.code}:${issue.groupId}:${index}`)) }),
83
+ error && /* @__PURE__ */ jsx("p", { role: "alert", children: error }),
84
+ line && /* @__PURE__ */ jsxs("p", { "aria-live": "polite", children: [
85
+ "Estimated total: ",
86
+ /* @__PURE__ */ jsx(Money, { value: configuration.total })
87
+ ] }),
88
+ /* @__PURE__ */ jsxs("footer", { className: "z-base-item-purchase", children: [
89
+ /* @__PURE__ */ jsxs(
90
+ Quantity.Root,
91
+ {
92
+ className: "z-base-quantity",
93
+ value: configuration.quantity,
94
+ min: item.quantity.min,
95
+ max: Math.min(item.quantity.max ?? 99, 99),
96
+ step: item.quantity.step,
97
+ onValueChange: configuration.setQuantity,
98
+ children: [
99
+ /* @__PURE__ */ jsx(Quantity.Decrement, { "aria-label": "Decrease quantity", children: "\u2212" }),
100
+ /* @__PURE__ */ jsx(Quantity.Value, { "aria-label": "Item quantity" }),
101
+ /* @__PURE__ */ jsx(Quantity.Increment, { "aria-label": "Increase quantity", children: "+" })
102
+ ]
103
+ }
104
+ ),
105
+ /* @__PURE__ */ jsxs(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ className: "z-base-button",
110
+ disabled: !restored || !item.isAvailable,
111
+ onClick: () => {
112
+ try {
113
+ configuration.add();
114
+ } catch (failure) {
115
+ setError(
116
+ failure instanceof Error ? failure.message : "Unable to save this item. Please try again."
117
+ );
118
+ }
119
+ },
120
+ children: [
121
+ item.isAvailable ? line ? "Save changes" : "Add" : item.stockLabel ?? "Unavailable",
122
+ " ",
123
+ !line && /* @__PURE__ */ jsx(Money, { value: configuration.total })
124
+ ]
125
+ }
126
+ )
127
+ ] })
128
+ ] })
129
+ }
130
+ );
131
+ }
132
+ export {
133
+ ItemConfigurator
134
+ };
135
+ //# sourceMappingURL=configurator.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/item/configurator.tsx"],
4
+ "sourcesContent": ["\"use client\";\nimport { ItemForm, Money, Quantity } from \"@zappie/foundations\";\nimport type { CartLine, Item } from \"@zappie/sdk\";\nimport { useZappie } from \"@zappie/sdk/react\";\nimport { countEvent } from \"@zappie/sdk/visits\";\nimport { Fragment, useState, type ReactNode } from \"react\";\nimport { LineOptions } from \"../cart/line-options\";\nimport { createConfiguratorCommit } from \"./configurator-commit\";\nimport { useConfiguratorDraft } from \"./configurator-draft\";\nimport { ItemNote } from \"./note\";\nimport { VariantStatus } from \"./variant-status\";\n\n/** The same draft and validation workflow for an item, an inline row and a cart edit. */\nexport function ItemConfigurator({\n item,\n menuId,\n line,\n onComplete,\n scope,\n showPrice = false,\n introduction,\n}: {\n item: Item;\n menuId?: string;\n line?: CartLine;\n onComplete(): void;\n scope: string;\n showPrice?: boolean;\n introduction?: ReactNode;\n}) {\n const client = useZappie();\n const { clear, restored, setValue, value } = useConfiguratorDraft({\n item,\n ...(menuId !== undefined ? { menuId } : {}),\n ...(line !== undefined ? { line } : {}),\n scope,\n });\n const [error, setError] = useState<string>();\n const onCommit = createConfiguratorCommit(client, line);\n return (\n <ItemForm.Root\n item={item}\n value={value}\n onValueChange={(next) => {\n const nextValue = { ...next };\n delete nextValue.variantId;\n setValue(nextValue);\n setError(undefined);\n }}\n {...(onCommit ? { onCommit } : {})}\n onAdded={() => {\n if (!line) {\n countEvent(\"add\");\n }\n clear();\n onComplete();\n }}\n className=\"z-base-configurator\"\n >\n {(configuration) => (\n <Fragment>\n <div className=\"z-base-item-summary\">\n {showPrice && (\n <p className=\"z-base-item-price\">\n <Money value={configuration.unitPrice} />\n {item.compareAtPrice && (\n <del>\n <Money value={item.compareAtPrice} />\n </del>\n )}\n </p>\n )}\n {!line && (\n <ItemNote\n id={item.id}\n value={value.note ?? \"\"}\n onChange={(note) => configuration.setValue({ ...value, note })}\n />\n )}\n </div>\n {line && (\n <label className=\"z-base-field\">\n Note\n <textarea\n className=\"z-base-input\"\n maxLength={line ? 280 : Math.max(35, value.note?.length ?? 0)}\n value={value.note ?? \"\"}\n onChange={(event) =>\n configuration.setValue({ ...value, note: event.target.value })\n }\n />\n </label>\n )}\n {showPrice && (\n <VariantStatus item={item} value={configuration.value} />\n )}\n {introduction}\n <LineOptions />\n {configuration.issues.length > 0 && (\n <div role=\"alert\">\n {configuration.issues.map((issue, index) => (\n <p key={`${issue.code}:${issue.groupId}:${index}`}>\n {issue.message}\n </p>\n ))}\n </div>\n )}\n {error && <p role=\"alert\">{error}</p>}\n {line && (\n <p aria-live=\"polite\">\n Estimated total: <Money value={configuration.total} />\n </p>\n )}\n <footer className=\"z-base-item-purchase\">\n <Quantity.Root\n className=\"z-base-quantity\"\n value={configuration.quantity}\n min={item.quantity.min}\n max={Math.min(item.quantity.max ?? 99, 99)}\n step={item.quantity.step}\n onValueChange={configuration.setQuantity}\n >\n <Quantity.Decrement aria-label=\"Decrease quantity\">\n \u2212\n </Quantity.Decrement>\n <Quantity.Value aria-label=\"Item quantity\" />\n <Quantity.Increment aria-label=\"Increase quantity\">\n +\n </Quantity.Increment>\n </Quantity.Root>\n <button\n type=\"button\"\n className=\"z-base-button\"\n disabled={!restored || !item.isAvailable}\n onClick={() => {\n try {\n configuration.add();\n } catch (failure) {\n setError(\n failure instanceof Error\n ? failure.message\n : \"Unable to save this item. Please try again.\",\n );\n }\n }}\n >\n {item.isAvailable\n ? line\n ? \"Save changes\"\n : \"Add\"\n : (item.stockLabel ?? \"Unavailable\")}{\" \"}\n {!line && <Money value={configuration.total} />}\n </button>\n </footer>\n </Fragment>\n )}\n </ItemForm.Root>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,65 @@
1
+ "use client";
2
+
3
+ // src/item/note.tsx
4
+ import { Overlay, useOverlay } from "@zappie/foundations";
5
+ import { useThemeClass } from "../cart/theme-class.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ function ItemNote({
8
+ id,
9
+ value,
10
+ onChange
11
+ }) {
12
+ const overlay = useOverlay("product_note", id);
13
+ const themeClass = useThemeClass("z-base-cart z-base-note");
14
+ return /* @__PURE__ */ jsxs(
15
+ Overlay.Root,
16
+ {
17
+ param: "product_note",
18
+ id,
19
+ presentation: { base: "drawer", lg: "dialog" },
20
+ children: [
21
+ /* @__PURE__ */ jsx(Overlay.Trigger, { className: "z-base-button-secondary", children: value ? "Edit Note" : "Add Note" }),
22
+ /* @__PURE__ */ jsxs(Overlay.Content, { "data-zappie-theme": "base", className: themeClass, children: [
23
+ /* @__PURE__ */ jsxs("header", { className: "z-base-cart-header", children: [
24
+ /* @__PURE__ */ jsx(Overlay.Title, { children: "Add a note" }),
25
+ /* @__PURE__ */ jsx(
26
+ Overlay.Close,
27
+ {
28
+ className: "z-base-button-secondary",
29
+ "aria-label": "Close note",
30
+ children: "\u2715"
31
+ }
32
+ )
33
+ ] }),
34
+ /* @__PURE__ */ jsxs("div", { className: "z-base-cart-body", children: [
35
+ /* @__PURE__ */ jsxs("label", { className: "z-base-field", children: [
36
+ "Note",
37
+ /* @__PURE__ */ jsx(
38
+ "textarea",
39
+ {
40
+ className: "z-base-input",
41
+ maxLength: Math.max(35, value.length),
42
+ value,
43
+ onChange: (event) => onChange(event.target.value)
44
+ }
45
+ )
46
+ ] }),
47
+ /* @__PURE__ */ jsx(
48
+ "button",
49
+ {
50
+ type: "button",
51
+ className: "z-base-button",
52
+ onClick: overlay.close,
53
+ children: "Add note"
54
+ }
55
+ )
56
+ ] })
57
+ ] })
58
+ ]
59
+ }
60
+ );
61
+ }
62
+ export {
63
+ ItemNote
64
+ };
65
+ //# sourceMappingURL=note.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/item/note.tsx"],
4
+ "sourcesContent": ["\"use client\";\nimport { Overlay, useOverlay } from \"@zappie/foundations\";\nimport { useThemeClass } from \"../cart/theme-class\";\nexport function ItemNote({\n id,\n value,\n onChange,\n}: {\n id: string;\n value: string;\n onChange(value: string): void;\n}) {\n const overlay = useOverlay(\"product_note\", id);\n const themeClass = useThemeClass(\"z-base-cart z-base-note\");\n return (\n <Overlay.Root\n param=\"product_note\"\n id={id}\n presentation={{ base: \"drawer\", lg: \"dialog\" }}\n >\n <Overlay.Trigger className=\"z-base-button-secondary\">\n {value ? \"Edit Note\" : \"Add Note\"}\n </Overlay.Trigger>\n <Overlay.Content data-zappie-theme=\"base\" className={themeClass}>\n <header className=\"z-base-cart-header\">\n <Overlay.Title>Add a note</Overlay.Title>\n <Overlay.Close\n className=\"z-base-button-secondary\"\n aria-label=\"Close note\"\n >\n \u2715\n </Overlay.Close>\n </header>\n <div className=\"z-base-cart-body\">\n <label className=\"z-base-field\">\n Note\n <textarea\n className=\"z-base-input\"\n maxLength={Math.max(35, value.length)}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n />\n </label>\n <button\n type=\"button\"\n className=\"z-base-button\"\n onClick={overlay.close}\n >\n Add note\n </button>\n </div>\n </Overlay.Content>\n </Overlay.Root>\n );\n}\n"],
5
+ "mappings": ";;;AACA,SAAS,SAAS,kBAAkB;AACpC,SAAS,qBAAqB;AAkBxB,cAIE,YAJF;AAjBC,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,UAAU,WAAW,gBAAgB,EAAE;AAC7C,QAAM,aAAa,cAAc,yBAAyB;AAC1D,SACE;AAAA,IAAC,QAAQ;AAAA,IAAR;AAAA,MACC,OAAM;AAAA,MACN;AAAA,MACA,cAAc,EAAE,MAAM,UAAU,IAAI,SAAS;AAAA,MAE7C;AAAA,4BAAC,QAAQ,SAAR,EAAgB,WAAU,2BACxB,kBAAQ,cAAc,YACzB;AAAA,QACA,qBAAC,QAAQ,SAAR,EAAgB,qBAAkB,QAAO,WAAW,YACnD;AAAA,+BAAC,YAAO,WAAU,sBAChB;AAAA,gCAAC,QAAQ,OAAR,EAAc,wBAAU;AAAA,YACzB;AAAA,cAAC,QAAQ;AAAA,cAAR;AAAA,gBACC,WAAU;AAAA,gBACV,cAAW;AAAA,gBACZ;AAAA;AAAA,YAED;AAAA,aACF;AAAA,UACA,qBAAC,SAAI,WAAU,oBACb;AAAA,iCAAC,WAAM,WAAU,gBAAe;AAAA;AAAA,cAE9B;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,WAAW,KAAK,IAAI,IAAI,MAAM,MAAM;AAAA,kBACpC;AAAA,kBACA,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA;AAAA,cAClD;AAAA,eACF;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,SAAS,QAAQ;AAAA,gBAClB;AAAA;AAAA,YAED;AAAA,aACF;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,23 @@
1
+ // src/item/variant-status.tsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ function VariantStatus({
4
+ item,
5
+ value
6
+ }) {
7
+ const matches = item.variants.filter(
8
+ (variant) => Object.entries(variant.attributeChoices).every(
9
+ ([groupId, choiceId]) => value.choices?.some(
10
+ (choice) => choice.groupId === groupId && choice.choiceId === choiceId
11
+ )
12
+ )
13
+ );
14
+ const selected = matches.length === 1 ? matches[0] : void 0;
15
+ if (!item.isAvailable || !selected) {
16
+ return null;
17
+ }
18
+ return !selected.isAvailable ? /* @__PURE__ */ jsx("p", { role: "status", children: "Out of stock" }) : selected.lowStock ? /* @__PURE__ */ jsx("p", { role: "status", children: "Low stock" }) : null;
19
+ }
20
+ export {
21
+ VariantStatus
22
+ };
23
+ //# sourceMappingURL=variant-status.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/item/variant-status.tsx"],
4
+ "sourcesContent": ["import type { CartLineInput, Item } from \"@zappie/sdk\";\n\nexport function VariantStatus({\n item,\n value,\n}: {\n item: Item;\n value: CartLineInput;\n}) {\n const matches = item.variants.filter((variant) =>\n Object.entries(variant.attributeChoices).every(([groupId, choiceId]) =>\n value.choices?.some(\n (choice) => choice.groupId === groupId && choice.choiceId === choiceId,\n ),\n ),\n );\n const selected = matches.length === 1 ? matches[0] : undefined;\n if (!item.isAvailable || !selected) {\n return null;\n }\n return !selected.isAvailable ? (\n <p role=\"status\">Out of stock</p>\n ) : selected.lowStock ? (\n <p role=\"status\">Low stock</p>\n ) : null;\n}\n"],
5
+ "mappings": ";AAqBI;AAnBG,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AACF,GAGG;AACD,QAAM,UAAU,KAAK,SAAS;AAAA,IAAO,CAAC,YACpC,OAAO,QAAQ,QAAQ,gBAAgB,EAAE;AAAA,MAAM,CAAC,CAAC,SAAS,QAAQ,MAChE,MAAM,SAAS;AAAA,QACb,CAAC,WAAW,OAAO,YAAY,WAAW,OAAO,aAAa;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,QAAQ,WAAW,IAAI,QAAQ,CAAC,IAAI;AACrD,MAAI,CAAC,KAAK,eAAe,CAAC,UAAU;AAClC,WAAO;AAAA,EACT;AACA,SAAO,CAAC,SAAS,cACf,oBAAC,OAAE,MAAK,UAAS,0BAAY,IAC3B,SAAS,WACX,oBAAC,OAAE,MAAK,UAAS,uBAAS,IACxB;AACN;",
6
+ "names": []
7
+ }
@@ -1,5 +1,62 @@
1
1
  "use client";
2
- export { ItemEscapeContext, ItemFrame } from './chunk-VIAJ27YC.js';
3
- import './chunk-JFEI2OUZ.js';
2
+
3
+ // src/item/frame.tsx
4
+ import { Overlay } from "@zappie/foundations";
5
+ import { createContext, useRef } from "react";
6
+ import { ThemeClassProvider } from "./cart/theme-class.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var ItemEscapeContext = createContext(null);
9
+ function ItemFrame({
10
+ id,
11
+ name,
12
+ hasImages,
13
+ navigation,
14
+ themeClass,
15
+ children
16
+ }) {
17
+ const escape = useRef(void 0);
18
+ const classes = [
19
+ "z-base-cart z-base-item",
20
+ hasImages ? "z-base-item-with-media" : "",
21
+ themeClass
22
+ ].filter(Boolean).join(" ");
23
+ return /* @__PURE__ */ jsx(ItemEscapeContext.Provider, { value: escape, children: /* @__PURE__ */ jsx(ThemeClassProvider, { value: themeClass, children: /* @__PURE__ */ jsx(
24
+ Overlay.Root,
25
+ {
26
+ param: "modal_id",
27
+ id: `product_${id}`,
28
+ navigation,
29
+ presentation: { base: "drawer", lg: "dialog" },
30
+ children: /* @__PURE__ */ jsxs(
31
+ Overlay.Content,
32
+ {
33
+ "data-zappie-theme": "base",
34
+ className: classes,
35
+ "aria-label": name,
36
+ onEscape: (event) => {
37
+ if (escape.current) {
38
+ event.preventDefault();
39
+ escape.current();
40
+ }
41
+ },
42
+ children: [
43
+ /* @__PURE__ */ jsx("header", { className: "z-base-item-header", children: /* @__PURE__ */ jsx(
44
+ Overlay.Close,
45
+ {
46
+ className: "z-base-button-secondary",
47
+ "aria-label": "Close product",
48
+ children: "\u2715"
49
+ }
50
+ ) }),
51
+ children
52
+ ]
53
+ }
54
+ )
55
+ }
56
+ ) }) });
57
+ }
58
+ export {
59
+ ItemEscapeContext,
60
+ ItemFrame
61
+ };
4
62
  //# sourceMappingURL=item-frame.js.map
5
- //# sourceMappingURL=item-frame.js.map
@@ -1 +1,7 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"item-frame.js"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/item/frame.tsx"],
4
+ "sourcesContent": ["\"use client\";\nimport { Overlay } from \"@zappie/foundations\";\nimport { createContext, useRef, type ReactNode, type RefObject } from \"react\";\nimport { ThemeClassProvider } from \"../cart/theme-class\";\nexport const ItemEscapeContext = createContext<RefObject<\n (() => void) | undefined\n> | null>(null);\n/** The eager modal frame stays mounted while the configurator chunk loads. */\nexport function ItemFrame({\n id,\n name,\n hasImages,\n navigation,\n themeClass,\n children,\n}: {\n id: string;\n name: string;\n hasImages?: boolean;\n themeClass?: string | undefined;\n children: ReactNode;\n navigation: { isOpen: boolean; open(): void; close(): void };\n}) {\n const escape = useRef<(() => void) | undefined>(undefined);\n const classes = [\n \"z-base-cart z-base-item\",\n hasImages ? \"z-base-item-with-media\" : \"\",\n themeClass,\n ]\n .filter(Boolean)\n .join(\" \");\n return (\n <ItemEscapeContext.Provider value={escape}>\n <ThemeClassProvider value={themeClass}>\n <Overlay.Root\n param=\"modal_id\"\n id={`product_${id}`}\n navigation={navigation}\n presentation={{ base: \"drawer\", lg: \"dialog\" }}\n >\n <Overlay.Content\n data-zappie-theme=\"base\"\n className={classes}\n aria-label={name}\n onEscape={(event) => {\n if (escape.current) {\n event.preventDefault();\n escape.current();\n }\n }}\n >\n <header className=\"z-base-item-header\">\n <Overlay.Close\n className=\"z-base-button-secondary\"\n aria-label=\"Close product\"\n >\n \u2715\n </Overlay.Close>\n </header>\n {children}\n </Overlay.Content>\n </Overlay.Root>\n </ThemeClassProvider>\n </ItemEscapeContext.Provider>\n );\n}\n"],
5
+ "mappings": ";;;AACA,SAAS,eAAe;AACxB,SAAS,eAAe,cAA8C;AACtE,SAAS,0BAA0B;AAqCzB,SAYI,KAZJ;AApCH,IAAM,oBAAoB,cAEvB,IAAI;AAEP,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,SAAS,OAAiC,MAAS;AACzD,QAAM,UAAU;AAAA,IACd;AAAA,IACA,YAAY,2BAA2B;AAAA,IACvC;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,SACE,oBAAC,kBAAkB,UAAlB,EAA2B,OAAO,QACjC,8BAAC,sBAAmB,OAAO,YACzB;AAAA,IAAC,QAAQ;AAAA,IAAR;AAAA,MACC,OAAM;AAAA,MACN,IAAI,WAAW,EAAE;AAAA,MACjB;AAAA,MACA,cAAc,EAAE,MAAM,UAAU,IAAI,SAAS;AAAA,MAE7C;AAAA,QAAC,QAAQ;AAAA,QAAR;AAAA,UACC,qBAAkB;AAAA,UAClB,WAAW;AAAA,UACX,cAAY;AAAA,UACZ,UAAU,CAAC,UAAU;AACnB,gBAAI,OAAO,SAAS;AAClB,oBAAM,eAAe;AACrB,qBAAO,QAAQ;AAAA,YACjB;AAAA,UACF;AAAA,UAEA;AAAA,gCAAC,YAAO,WAAU,sBAChB;AAAA,cAAC,QAAQ;AAAA,cAAR;AAAA,gBACC,WAAU;AAAA,gBACV,cAAW;AAAA,gBACZ;AAAA;AAAA,YAED,GACF;AAAA,YACC;AAAA;AAAA;AAAA,MACH;AAAA;AAAA,EACF,GACF,GACF;AAEJ;",
6
+ "names": []
7
+ }
package/dist/item.js CHANGED
@@ -1,13 +1,12 @@
1
1
  "use client";
2
- import { ItemFrame, ItemEscapeContext } from './chunk-VIAJ27YC.js';
3
- import { ItemImage, Description } from './chunk-USSLDBDY.js';
4
- import { ItemConfigurator } from './chunk-2MV6KU3R.js';
5
- import './chunk-QWST2TA2.js';
6
- import './chunk-JFEI2OUZ.js';
7
- import { Overlay } from '@zappie/foundations';
8
- import { useState, useContext, useEffect, Fragment } from 'react';
9
- import { jsx, jsxs } from 'react/jsx-runtime';
10
2
 
3
+ // src/item/item-detail.tsx
4
+ import { Overlay } from "@zappie/foundations";
5
+ import { Fragment, useContext, useEffect, useState } from "react";
6
+ import { Description, ItemImage } from "./catalogue/presentation.js";
7
+ import { ItemConfigurator } from "./item/configurator.js";
8
+ import { ItemEscapeContext, ItemFrame } from "./item-frame.js";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
11
10
  function ItemDetail(props) {
12
11
  return /* @__PURE__ */ jsx(
13
12
  ItemFrame,
@@ -147,7 +146,8 @@ function ItemContent({
147
146
  }
148
147
  );
149
148
  }
150
-
151
- export { ItemContent, ItemDetail };
149
+ export {
150
+ ItemContent,
151
+ ItemDetail
152
+ };
152
153
  //# sourceMappingURL=item.js.map
153
- //# sourceMappingURL=item.js.map
package/dist/item.js.map CHANGED
@@ -1 +1,7 @@
1
- {"version":3,"sources":["../src/item/item-detail.tsx"],"names":[],"mappings":"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","file":"item.js","sourcesContent":["\"use client\";\nimport { Overlay } from \"@zappie/foundations\";\nimport type { Item } from \"@zappie/sdk\";\nimport { Fragment, useContext, useEffect, useState } from \"react\";\nimport { Description, ItemImage } from \"../catalogue/presentation\";\nimport { ItemConfigurator } from \"./configurator\";\nimport { ItemEscapeContext, ItemFrame } from \"./frame\";\n\nexport type ItemDetailProps = {\n item: Item;\n menuId: string;\n scope: string;\n href: string;\n themeClass?: string;\n navigation: { isOpen: boolean; open(): void; close(): void };\n};\n/** Framework-independent SDK item screen, reusable through themeClass. */\nexport function ItemDetail(props: ItemDetailProps) {\n return (\n <ItemFrame\n id={props.item.id}\n name={props.item.name}\n hasImages={props.item.images.length > 0}\n navigation={props.navigation}\n themeClass={props.themeClass}\n >\n <ItemContent key={props.item.id} {...props} />\n </ItemFrame>\n );\n}\nexport function ItemContent({\n item,\n menuId,\n scope,\n href,\n navigation,\n}: ItemDetailProps) {\n const [image, setImage] = useState(0);\n const [lightbox, setLightbox] = useState(false);\n const [shareMessage, setShareMessage] = useState(\"\");\n const escape = useContext(ItemEscapeContext);\n useEffect(() => {\n if (!escape) {\n return;\n }\n escape.current = lightbox ? () => setLightbox(false) : undefined;\n return () => {\n escape.current = undefined;\n };\n }, [escape, lightbox]);\n return (\n <div\n className={`z-base-item-layout ${lightbox ? \"z-base-item-lightbox\" : \"\"}`}\n >\n {item.images.length > 0 && (\n <section className=\"z-base-item-media\" aria-label=\"Product images\">\n <button\n type=\"button\"\n className=\"z-base-item-photo\"\n aria-label={\n lightbox ? \"Close enlarged image\" : \"Enlarge product image\"\n }\n onClick={() => setLightbox(!lightbox)}\n >\n <ItemImage\n key={image}\n src={item.images[image] ?? item.images[0] ?? \"\"}\n sizes=\"(min-width: 768px) 450px, 100vw\"\n priority\n />\n </button>\n {item.images.length > 1 && (\n <nav aria-label=\"Image gallery\">\n <button\n type=\"button\"\n onClick={() =>\n setImage(\n (image + item.images.length - 1) % item.images.length,\n )\n }\n aria-label=\"Previous image\"\n >\n ←\n </button>\n <span>\n {image + 1} / {item.images.length}\n </span>\n <button\n type=\"button\"\n onClick={() => setImage((image + 1) % item.images.length)}\n aria-label=\"Next image\"\n >\n →\n </button>\n </nav>\n )}\n {lightbox && (\n <button\n type=\"button\"\n className=\"z-base-button-secondary\"\n onClick={() => setLightbox(false)}\n >\n Back to product\n </button>\n )}\n </section>\n )}\n {!lightbox && (\n <div className=\"z-base-item-details\">\n <button\n type=\"button\"\n className=\"z-base-button-secondary\"\n aria-label=\"Share product\"\n onClick={() => {\n const url = new URL(href, window.location.origin).href;\n void Promise.resolve()\n .then(() =>\n navigator.share\n ? navigator.share({ title: item.name, url })\n : navigator.clipboard\n .writeText(url)\n .then(() => setShareMessage(\"Link copied\")),\n )\n .catch((failure) => {\n if (failure?.name !== \"AbortError\") {\n setShareMessage(\n \"Could not share the link. Please try again.\",\n );\n }\n });\n }}\n >\n Share\n </button>\n <Overlay.Title>{item.name}</Overlay.Title>\n {!item.isAvailable && (\n <p role=\"status\">{item.stockLabel ?? \"Unavailable\"}</p>\n )}\n {shareMessage && <p role=\"status\">{shareMessage}</p>}\n <ItemConfigurator\n showPrice\n introduction={\n <Fragment>\n {item.promo && <p>{item.promo.name}</p>}\n {item.description && <Description value={item.description} />}\n </Fragment>\n }\n key={`${scope}:${item.id}:${menuId}`}\n item={item}\n menuId={menuId}\n scope={scope}\n onComplete={navigation.close}\n />\n </div>\n )}\n </div>\n );\n}\n"]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/item/item-detail.tsx"],
4
+ "sourcesContent": ["\"use client\";\nimport { Overlay } from \"@zappie/foundations\";\nimport type { Item } from \"@zappie/sdk\";\nimport { Fragment, useContext, useEffect, useState } from \"react\";\nimport { Description, ItemImage } from \"../catalogue/presentation\";\nimport { ItemConfigurator } from \"./configurator\";\nimport { ItemEscapeContext, ItemFrame } from \"./frame\";\n\nexport type ItemDetailProps = {\n item: Item;\n menuId: string;\n scope: string;\n href: string;\n themeClass?: string;\n navigation: { isOpen: boolean; open(): void; close(): void };\n};\n/** Framework-independent SDK item screen, reusable through themeClass. */\nexport function ItemDetail(props: ItemDetailProps) {\n return (\n <ItemFrame\n id={props.item.id}\n name={props.item.name}\n hasImages={props.item.images.length > 0}\n navigation={props.navigation}\n themeClass={props.themeClass}\n >\n <ItemContent key={props.item.id} {...props} />\n </ItemFrame>\n );\n}\nexport function ItemContent({\n item,\n menuId,\n scope,\n href,\n navigation,\n}: ItemDetailProps) {\n const [image, setImage] = useState(0);\n const [lightbox, setLightbox] = useState(false);\n const [shareMessage, setShareMessage] = useState(\"\");\n const escape = useContext(ItemEscapeContext);\n useEffect(() => {\n if (!escape) {\n return;\n }\n escape.current = lightbox ? () => setLightbox(false) : undefined;\n return () => {\n escape.current = undefined;\n };\n }, [escape, lightbox]);\n return (\n <div\n className={`z-base-item-layout ${lightbox ? \"z-base-item-lightbox\" : \"\"}`}\n >\n {item.images.length > 0 && (\n <section className=\"z-base-item-media\" aria-label=\"Product images\">\n <button\n type=\"button\"\n className=\"z-base-item-photo\"\n aria-label={\n lightbox ? \"Close enlarged image\" : \"Enlarge product image\"\n }\n onClick={() => setLightbox(!lightbox)}\n >\n <ItemImage\n key={image}\n src={item.images[image] ?? item.images[0] ?? \"\"}\n sizes=\"(min-width: 768px) 450px, 100vw\"\n priority\n />\n </button>\n {item.images.length > 1 && (\n <nav aria-label=\"Image gallery\">\n <button\n type=\"button\"\n onClick={() =>\n setImage(\n (image + item.images.length - 1) % item.images.length,\n )\n }\n aria-label=\"Previous image\"\n >\n \u2190\n </button>\n <span>\n {image + 1} / {item.images.length}\n </span>\n <button\n type=\"button\"\n onClick={() => setImage((image + 1) % item.images.length)}\n aria-label=\"Next image\"\n >\n \u2192\n </button>\n </nav>\n )}\n {lightbox && (\n <button\n type=\"button\"\n className=\"z-base-button-secondary\"\n onClick={() => setLightbox(false)}\n >\n Back to product\n </button>\n )}\n </section>\n )}\n {!lightbox && (\n <div className=\"z-base-item-details\">\n <button\n type=\"button\"\n className=\"z-base-button-secondary\"\n aria-label=\"Share product\"\n onClick={() => {\n const url = new URL(href, window.location.origin).href;\n void Promise.resolve()\n .then(() =>\n navigator.share\n ? navigator.share({ title: item.name, url })\n : navigator.clipboard\n .writeText(url)\n .then(() => setShareMessage(\"Link copied\")),\n )\n .catch((failure) => {\n if (failure?.name !== \"AbortError\") {\n setShareMessage(\n \"Could not share the link. Please try again.\",\n );\n }\n });\n }}\n >\n Share\n </button>\n <Overlay.Title>{item.name}</Overlay.Title>\n {!item.isAvailable && (\n <p role=\"status\">{item.stockLabel ?? \"Unavailable\"}</p>\n )}\n {shareMessage && <p role=\"status\">{shareMessage}</p>}\n <ItemConfigurator\n showPrice\n introduction={\n <Fragment>\n {item.promo && <p>{item.promo.name}</p>}\n {item.description && <Description value={item.description} />}\n </Fragment>\n }\n key={`${scope}:${item.id}:${menuId}`}\n item={item}\n menuId={menuId}\n scope={scope}\n onComplete={navigation.close}\n />\n </div>\n )}\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,4 +1,41 @@
1
1
  "use client";
2
- export { CatalogueNavigationProvider, createUrlNavigation, useCatalogueNavigation } from './chunk-ILOCSCZL.js';
2
+
3
+ // src/navigation.tsx
4
+ import {
5
+ createContext,
6
+ useContext,
7
+ useEffect,
8
+ useState
9
+ } from "react";
10
+ import { createUrlNavigation } from "./url-navigation.js";
11
+ import { jsx } from "react/jsx-runtime";
12
+ var Context = createContext(null);
13
+ function CatalogueNavigationProvider({
14
+ navigation,
15
+ children
16
+ }) {
17
+ const [, refresh] = useState(0);
18
+ useEffect(() => {
19
+ const update = () => refresh((value) => value + 1);
20
+ window.addEventListener("popstate", update);
21
+ return () => {
22
+ window.removeEventListener("popstate", update);
23
+ };
24
+ }, [navigation]);
25
+ return /* @__PURE__ */ jsx(Context.Provider, { value: navigation, children });
26
+ }
27
+ function useCatalogueNavigation() {
28
+ const navigation = useContext(Context);
29
+ if (!navigation) {
30
+ throw new Error(
31
+ "useCatalogueNavigation requires CatalogueNavigationProvider"
32
+ );
33
+ }
34
+ return navigation;
35
+ }
36
+ export {
37
+ CatalogueNavigationProvider,
38
+ createUrlNavigation,
39
+ useCatalogueNavigation
40
+ };
3
41
  //# sourceMappingURL=navigation.js.map
4
- //# sourceMappingURL=navigation.js.map
@@ -1 +1,7 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"navigation.js"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/navigation.tsx"],
4
+ "sourcesContent": ["\"use client\";\n\nimport type { Item } from \"@zappie/sdk\";\nimport type { StorefrontUrlOptions } from \"@zappie/sdk/url\";\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n type ReactNode,\n} from \"react\";\n\n/** URL-owned selection, shared by template routers and reusable base screens. */\nexport type CatalogueLocation = {\n pathname: string;\n menuId?: string;\n categoryId?: string;\n menuLayout?: \"GRID\" | \"LIST\" | \"CARD\";\n item?: { id: string; path: string; presentation: \"path\" | \"query\" };\n};\n\n/** Stable identities, not host selectors or retained DOM nodes. */\nexport type CatalogueFocusTarget = { itemId?: string; fallback: \"catalogue\" };\n\nexport type CatalogueNavigationTarget = {\n type: \"item\";\n itemId: string;\n menuId?: string;\n categoryId?: string;\n};\n\nexport type CatalogueNavigation = {\n /** Fresh URL snapshot on every read; providers re-render on history changes. */\n readonly location: CatalogueLocation;\n hrefFor(target: CatalogueNavigationTarget): string;\n selectMenu(menuId: string): void;\n selectCategory(categoryId: string): void;\n setLayout(layout: NonNullable<CatalogueLocation[\"menuLayout\"]>): void;\n openItem(input: {\n itemId: string;\n /** Already normalized catalogue/search item; opening it must not fetch it again. */\n item?: Item;\n menuId: string;\n categoryId?: string;\n }): Promise<void>;\n /** Resolves after history changes and the item releases its modal/focus lock. */\n closeItem(): Promise<void>;\n /** Close the active item/base overlay before opening another surface. */\n openCart(): Promise<void>;\n openBranchFinder(): Promise<void>;\n openBranchDetails?(): Promise<void>;\n switchFulfilment(mode: \"delivery\" | \"pickup\"): Promise<boolean>;\n /** Called after close settles; use a registered trigger, or the catalogue heading. */\n restoreFocus(target: CatalogueFocusTarget): void;\n};\n\nexport type UrlNavigationOptions = StorefrontUrlOptions & {\n window?: Window & typeof globalThis;\n};\nconst Context = createContext<CatalogueNavigation | null>(null);\n\nexport function CatalogueNavigationProvider({\n navigation,\n children,\n}: {\n navigation: CatalogueNavigation;\n children: ReactNode;\n}) {\n const [, refresh] = useState(0);\n useEffect(() => {\n const update = () => refresh((value) => value + 1);\n window.addEventListener(\"popstate\", update);\n return () => {\n window.removeEventListener(\"popstate\", update);\n };\n }, [navigation]);\n return <Context.Provider value={navigation}>{children}</Context.Provider>;\n}\n\nexport function useCatalogueNavigation() {\n const navigation = useContext(Context);\n if (!navigation) {\n throw new Error(\n \"useCatalogueNavigation requires CatalogueNavigationProvider\",\n );\n }\n return navigation;\n}\n\nexport { createUrlNavigation } from \"./url-navigation\";\n"],
5
+ "mappings": ";;;AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AA+EP,SAAS,2BAA2B;AAb3B;AAjBT,IAAM,UAAU,cAA0C,IAAI;AAEvD,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,EAAE,OAAO,IAAI,SAAS,CAAC;AAC9B,YAAU,MAAM;AACd,UAAM,SAAS,MAAM,QAAQ,CAAC,UAAU,QAAQ,CAAC;AACjD,WAAO,iBAAiB,YAAY,MAAM;AAC1C,WAAO,MAAM;AACX,aAAO,oBAAoB,YAAY,MAAM;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AACf,SAAO,oBAAC,QAAQ,UAAR,EAAiB,OAAO,YAAa,UAAS;AACxD;AAEO,SAAS,yBAAyB;AACvC,QAAM,aAAa,WAAW,OAAO;AACrC,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,61 @@
1
+ // src/url-navigation-state.ts
2
+ var NAVIGATION_ENTRY = "zappie:storefront-navigation-entry";
3
+ var routeBase = (route) => {
4
+ if (route.type === "item" || route.type === "order-menu") {
5
+ return {
6
+ business: route.business,
7
+ ...route.branch !== void 0 ? { branch: route.branch } : {}
8
+ };
9
+ }
10
+ return null;
11
+ };
12
+ var stateWith = (state, values) => {
13
+ const query = { ...state.query };
14
+ const next = { ...state, query };
15
+ const update = (property, key, value) => {
16
+ if (!Object.hasOwn(values, property)) {
17
+ return;
18
+ }
19
+ if (value === void 0) {
20
+ delete query[key];
21
+ delete next[property];
22
+ return;
23
+ }
24
+ query[key] = property === "mode" ? String(value === "pickup") : value;
25
+ if (property === "mode") {
26
+ next.mode = value === "pickup" ? "pickup" : "delivery";
27
+ } else if (property === "menuId") {
28
+ next.menuId = value;
29
+ } else if (property === "categoryId") {
30
+ next.categoryId = value;
31
+ } else if (property === "menuLayout") {
32
+ next.menuLayout = value;
33
+ } else {
34
+ next.modalId = value;
35
+ }
36
+ };
37
+ update("menuId", "menu_id", values.menuId);
38
+ update("categoryId", "category_id", values.categoryId);
39
+ update("menuLayout", "menu_layout", values.menuLayout);
40
+ update("modalId", "modal_id", values.modalId);
41
+ update("mode", "pickup", values.mode);
42
+ return next;
43
+ };
44
+ var catalogueRoute = (route, state) => {
45
+ const base = routeBase(route);
46
+ if (!base) {
47
+ return route;
48
+ }
49
+ return {
50
+ type: "order-menu",
51
+ ...base,
52
+ state
53
+ };
54
+ };
55
+ export {
56
+ NAVIGATION_ENTRY,
57
+ catalogueRoute,
58
+ routeBase,
59
+ stateWith
60
+ };
61
+ //# sourceMappingURL=url-navigation-state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/url-navigation-state.ts"],
4
+ "sourcesContent": ["import type { StorefrontPageState, StorefrontRoute } from \"@zappie/sdk/url\";\n\n/** History-state key marking entries this provider pushed, so close can go Back. */\nexport const NAVIGATION_ENTRY = \"zappie:storefront-navigation-entry\";\n\nexport const routeBase = (route: StorefrontRoute) => {\n if (route.type === \"item\" || route.type === \"order-menu\") {\n return {\n business: route.business,\n ...(route.branch !== undefined ? { branch: route.branch } : {}),\n };\n }\n return null;\n};\n\nexport const stateWith = (\n state: StorefrontPageState,\n values: {\n menuId?: string | undefined;\n categoryId?: string | undefined;\n menuLayout?: string | undefined;\n modalId?: string | undefined;\n mode?: \"delivery\" | \"pickup\" | undefined;\n },\n): StorefrontPageState => {\n const query = { ...state.query };\n const next: StorefrontPageState = { ...state, query };\n const update = (\n property: \"menuId\" | \"categoryId\" | \"menuLayout\" | \"modalId\" | \"mode\",\n key: string,\n value: string | undefined,\n ) => {\n if (!Object.hasOwn(values, property)) {\n return;\n }\n if (value === undefined) {\n delete query[key];\n delete next[property];\n return;\n }\n query[key] = property === \"mode\" ? String(value === \"pickup\") : value;\n if (property === \"mode\") {\n next.mode = value === \"pickup\" ? \"pickup\" : \"delivery\";\n } else if (property === \"menuId\") {\n next.menuId = value;\n } else if (property === \"categoryId\") {\n next.categoryId = value;\n } else if (property === \"menuLayout\") {\n next.menuLayout = value;\n } else {\n next.modalId = value;\n }\n };\n update(\"menuId\", \"menu_id\", values.menuId);\n update(\"categoryId\", \"category_id\", values.categoryId);\n update(\"menuLayout\", \"menu_layout\", values.menuLayout);\n update(\"modalId\", \"modal_id\", values.modalId);\n update(\"mode\", \"pickup\", values.mode);\n return next;\n};\n\nexport const catalogueRoute = (\n route: StorefrontRoute,\n state: StorefrontPageState,\n): StorefrontRoute => {\n const base = routeBase(route);\n if (!base) {\n return route;\n }\n return {\n type: \"order-menu\",\n ...base,\n state,\n };\n};\n"],
5
+ "mappings": ";AAGO,IAAM,mBAAmB;AAEzB,IAAM,YAAY,CAAC,UAA2B;AACnD,MAAI,MAAM,SAAS,UAAU,MAAM,SAAS,cAAc;AACxD,WAAO;AAAA,MACL,UAAU,MAAM;AAAA,MAChB,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,YAAY,CACvB,OACA,WAOwB;AACxB,QAAM,QAAQ,EAAE,GAAG,MAAM,MAAM;AAC/B,QAAM,OAA4B,EAAE,GAAG,OAAO,MAAM;AACpD,QAAM,SAAS,CACb,UACA,KACA,UACG;AACH,QAAI,CAAC,OAAO,OAAO,QAAQ,QAAQ,GAAG;AACpC;AAAA,IACF;AACA,QAAI,UAAU,QAAW;AACvB,aAAO,MAAM,GAAG;AAChB,aAAO,KAAK,QAAQ;AACpB;AAAA,IACF;AACA,UAAM,GAAG,IAAI,aAAa,SAAS,OAAO,UAAU,QAAQ,IAAI;AAChE,QAAI,aAAa,QAAQ;AACvB,WAAK,OAAO,UAAU,WAAW,WAAW;AAAA,IAC9C,WAAW,aAAa,UAAU;AAChC,WAAK,SAAS;AAAA,IAChB,WAAW,aAAa,cAAc;AACpC,WAAK,aAAa;AAAA,IACpB,WAAW,aAAa,cAAc;AACpC,WAAK,aAAa;AAAA,IACpB,OAAO;AACL,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AACA,SAAO,UAAU,WAAW,OAAO,MAAM;AACzC,SAAO,cAAc,eAAe,OAAO,UAAU;AACrD,SAAO,cAAc,eAAe,OAAO,UAAU;AACrD,SAAO,WAAW,YAAY,OAAO,OAAO;AAC5C,SAAO,QAAQ,UAAU,OAAO,IAAI;AACpC,SAAO;AACT;AAEO,IAAM,iBAAiB,CAC5B,OACA,UACoB;AACpB,QAAM,OAAO,UAAU,KAAK;AAC5B,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,GAAG;AAAA,IACH;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }