@riverbankcms/sdk 0.74.0 → 0.76.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.
Files changed (145) hide show
  1. package/README.md +2 -0
  2. package/dist/{PreviewEditorSidebar-5XL7M3OM.mjs → PreviewEditorSidebar-X2HWXFOL.mjs} +172 -89
  3. package/dist/{PreviewEditorUI-ZDFRDJID.mjs → PreviewEditorUI-AQXIXPOH.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-ZQNDCASH.mjs +8 -0
  5. package/dist/_dts/api/src/bookingOperations.d.ts +12 -0
  6. package/dist/_dts/api/src/cache-tags.d.ts +22 -0
  7. package/dist/_dts/api/src/contentRuntime.d.ts +1 -0
  8. package/dist/_dts/api/src/endpoints.d.ts +24 -24
  9. package/dist/_dts/api/src/index.d.ts +1 -1
  10. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +13 -4
  11. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +4 -2
  12. package/dist/_dts/block-form/src/client/index.d.ts +1 -1
  13. package/dist/_dts/block-form/src/manifest/utils.d.ts +24 -0
  14. package/dist/_dts/blocks/src/client/booking-form.d.ts +2 -0
  15. package/dist/_dts/blocks/src/client/carousel.d.ts +1 -0
  16. package/dist/_dts/blocks/src/client/course-registration.d.ts +2 -0
  17. package/dist/_dts/blocks/src/client/events.d.ts +6 -0
  18. package/dist/_dts/blocks/src/client/form.d.ts +2 -0
  19. package/dist/_dts/blocks/src/client/header.d.ts +1 -0
  20. package/dist/_dts/blocks/src/client/location-map.d.ts +1 -0
  21. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +2 -0
  22. package/dist/_dts/blocks/src/client/shop.d.ts +6 -0
  23. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -4
  24. package/dist/_dts/blocks/src/lib/video.d.ts +2 -0
  25. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +21 -1
  26. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +7 -6
  27. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +3 -3
  28. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +3 -2
  29. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +3 -27
  30. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +163 -0
  31. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +5 -5
  32. package/dist/_dts/blocks/src/system/runtime/nodes/events/index.d.ts +3 -0
  33. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.client.d.ts +1 -0
  34. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.server.d.ts +1 -0
  35. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionCompactRow.d.ts +29 -0
  36. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionList.d.ts +13 -0
  37. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +4 -0
  38. package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +4 -3
  39. package/dist/_dts/blocks/src/system/runtime/shared/utils/bookingRoute.d.ts +20 -0
  40. package/dist/_dts/blocks/src/system/runtime/shared/utils/index.d.ts +2 -1
  41. package/dist/_dts/blocks/src/system/types/link.d.ts +12 -0
  42. package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +5 -0
  43. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +2 -0
  44. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +3 -1
  45. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +3 -1
  46. package/dist/_dts/editor-blocks/src/block-editor/BlockSettingsModal.d.ts +5 -1
  47. package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +2 -0
  48. package/dist/_dts/editor-blocks/src/block-editor/actionControlMode.d.ts +2 -0
  49. package/dist/_dts/editor-blocks/src/index.d.ts +1 -1
  50. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +12 -2
  51. package/dist/_dts/preview-next/src/client/preview/themeOverlay.d.ts +21 -3
  52. package/dist/_dts/sdk/src/components.d.ts +2 -2
  53. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -0
  54. package/dist/_dts/sdk/src/rendering/index.d.ts +2 -2
  55. package/dist/_dts/sdk/src/rendering/islands/deferredVideoEmbeds.d.ts +2 -0
  56. package/dist/_dts/sdk/src/rendering/overrideResolution.d.ts +6 -0
  57. package/dist/_dts/sdk/src/rendering/overrides.d.ts +21 -1
  58. package/dist/_dts/sdk/src/rendering/server.d.ts +4 -0
  59. package/dist/_dts/sdk/src/version.d.ts +1 -1
  60. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  61. package/dist/{chunk-2MIWNFJM.mjs → chunk-LYI7TEMH.mjs} +494 -171
  62. package/dist/{chunk-YY7K3QD2.mjs → chunk-Q4OLG66B.mjs} +9 -9
  63. package/dist/{chunk-CEQBBLMJ.mjs → chunk-TW2Y4RR5.mjs} +69 -14
  64. package/dist/{chunk-CBD47MTM.mjs → chunk-V5VORNEJ.mjs} +2 -2
  65. package/dist/{chunk-7RX72SK2.mjs → chunk-VX7B5VAC.mjs} +36 -25
  66. package/dist/{chunk-YRJKZEQ3.mjs → chunk-Z7JLNTJR.mjs} +1 -1
  67. package/dist/cli/index.mjs +3395 -3753
  68. package/dist/client/{accordion-ZZVXWV3N.mjs → accordion-2YHIBOZH.mjs} +1 -1
  69. package/dist/client/bookingForm-35IBDWAS.mjs +3012 -0
  70. package/dist/client/bookings.mjs +30 -21
  71. package/dist/client/{carousel-25WK2H7G.mjs → carousel-K6XG7NZQ.mjs} +3 -2
  72. package/dist/client/cart-HCFYUTTU.mjs +18 -0
  73. package/dist/client/checkout-J3U4XR7K.mjs +18 -0
  74. package/dist/client/chunk-3DCJ45Z2.mjs +36 -0
  75. package/dist/client/chunk-3PEDD5KJ.mjs +146 -0
  76. package/dist/client/{chunk-6VGXRE34.mjs → chunk-7UOSCYY4.mjs} +76 -29
  77. package/dist/client/chunk-BOIHIU7E.mjs +106 -0
  78. package/dist/client/chunk-F7LHOKEH.mjs +146 -0
  79. package/dist/client/chunk-FGUIVT2B.mjs +204 -0
  80. package/dist/client/chunk-I2MMZO53.mjs +6 -0
  81. package/dist/client/chunk-II7O4XN3.mjs +2206 -0
  82. package/dist/client/chunk-J227A3CQ.mjs +245 -0
  83. package/dist/client/chunk-JEZECJ3W.mjs +383 -0
  84. package/dist/client/chunk-M3L3KYYR.mjs +1181 -0
  85. package/dist/client/chunk-OJPZEZU2.mjs +31 -0
  86. package/dist/client/chunk-PFBX3IQL.mjs +1378 -0
  87. package/dist/client/chunk-RTZ3JKKX.mjs +178 -0
  88. package/dist/client/chunk-SNSWVZEP.mjs +5592 -0
  89. package/dist/client/chunk-TQ5MSPDX.mjs +74 -0
  90. package/dist/client/chunk-YLMKMCSJ.mjs +86 -0
  91. package/dist/client/client.mjs +54052 -54518
  92. package/dist/client/courseRegistration-ZBXS7VGI.mjs +1737 -0
  93. package/dist/client/{eventCalendar-X6GIPYFM.mjs → eventCalendar-EQQZHJBA.mjs} +13 -2
  94. package/dist/client/{eventCombined-EZUOPM3G.mjs → eventCombined-JCFTGBFQ.mjs} +13 -2
  95. package/dist/client/eventDetails-HLUTQSYY.mjs +25 -0
  96. package/dist/client/{eventListing-HEFGAETC.mjs → eventListing-FG4MICVB.mjs} +13 -2
  97. package/dist/client/{eventRegistration-3LCP2V3P.mjs → eventRegistration-GUEB7LBT.mjs} +13 -2
  98. package/dist/client/form-YQEW4YIT.mjs +300 -0
  99. package/dist/client/headerSection-GTR3TTRM.mjs +729 -0
  100. package/dist/client/hooks.mjs +49 -33
  101. package/dist/client/locationMap-SPC7VGUH.mjs +227 -0
  102. package/dist/client/newsletterForm-4IW5BLID.mjs +208 -0
  103. package/dist/client/productDetail-KP5H2WJO.mjs +18 -0
  104. package/dist/client/productList-3M3M72XZ.mjs +18 -0
  105. package/dist/client/rendering/client.mjs +15580 -16277
  106. package/dist/client/rendering/islands.mjs +98 -21
  107. package/dist/client/rendering.mjs +48730 -49191
  108. package/dist/client/shop-ACQKVGOM.mjs +20 -0
  109. package/dist/preview-next/before-render.mjs +37 -25
  110. package/dist/preview-next/chrome.css +1 -1
  111. package/dist/preview-next/client/runtime.mjs +5 -5
  112. package/dist/preview-next/editor-base.css +2 -148
  113. package/dist/preview-next/editor-chrome.css +179 -0
  114. package/dist/preview-next/middleware.mjs +37 -25
  115. package/dist/{sdk-runtime-OHNONZ5U.mjs → sdk-runtime-K7HNB4U2.mjs} +6 -6
  116. package/dist/server/components.mjs +1294 -1103
  117. package/dist/server/config-validation.mjs +49 -33
  118. package/dist/server/config.mjs +49 -33
  119. package/dist/server/data.mjs +49 -33
  120. package/dist/server/index.mjs +45 -33
  121. package/dist/server/next.mjs +1240 -1050
  122. package/dist/server/page-converter.mjs +12 -8
  123. package/dist/server/prebuild.mjs +1 -1
  124. package/dist/server/rendering/server.mjs +1389 -1104
  125. package/dist/server/rendering.mjs +1300 -1109
  126. package/dist/server/routing.mjs +49 -33
  127. package/dist/server/server.mjs +50 -34
  128. package/dist/server/theme-bridge.mjs +5 -0
  129. package/dist/styles/index.css +5 -0
  130. package/package.json +2 -1
  131. package/dist/SdkPreviewModeRuntime-CRYNDSPL.mjs +0 -8
  132. package/dist/client/bookingForm-4X77HKDS.mjs +0 -34
  133. package/dist/client/cart-JWD2VRFU.mjs +0 -11
  134. package/dist/client/checkout-V7KYGWL7.mjs +0 -11
  135. package/dist/client/chunk-5IYGMTUE.mjs +0 -18614
  136. package/dist/client/chunk-RKCFVIMS.mjs +0 -26
  137. package/dist/client/courseRegistration-O6ZPK4YT.mjs +0 -29
  138. package/dist/client/eventDetails-3WODIXET.mjs +0 -14
  139. package/dist/client/form-AKXQMY6Z.mjs +0 -85
  140. package/dist/client/headerSection-5KHCMU6B.mjs +0 -12
  141. package/dist/client/locationMap-7HIADW76.mjs +0 -14
  142. package/dist/client/newsletterForm-5N4YTMU3.mjs +0 -60
  143. package/dist/client/productDetail-IZUA7ZP3.mjs +0 -11
  144. package/dist/client/productList-KWIIJE6I.mjs +0 -11
  145. package/dist/client/shop-XZQFRQWZ.mjs +0 -13
@@ -5797,6 +5797,17 @@ function getBookingSuccessMessage(successMessage) {
5797
5797
  return successMessage?.trim() || "Your appointment has been booked! Check your email for confirmation.";
5798
5798
  }
5799
5799
 
5800
+ // ../logger/src/noop.ts
5801
+ var noop = () => {
5802
+ };
5803
+ var logger = {
5804
+ debug: noop,
5805
+ info: noop,
5806
+ warn: noop,
5807
+ error: noop,
5808
+ withFields: (_) => logger
5809
+ };
5810
+
5800
5811
  // ../theme-core/src/inputs/types.ts
5801
5812
  import { z as z6 } from "zod";
5802
5813
  var inputSystemSchema = z6.object({
@@ -6157,17 +6168,6 @@ function FeedbackMessage({
6157
6168
  // ../blocks/src/system/runtime/nodes/booking-form.client.tsx
6158
6169
  import React3, { useRef as useRef7, useState as useState6 } from "react";
6159
6170
 
6160
- // ../logger/src/noop.ts
6161
- var noop = () => {
6162
- };
6163
- var logger = {
6164
- debug: noop,
6165
- info: noop,
6166
- warn: noop,
6167
- error: noop,
6168
- withFields: (_) => logger
6169
- };
6170
-
6171
6171
  // ../altcha/src/AltchaWidget.tsx
6172
6172
  import { useEffect, useRef, useState } from "react";
6173
6173
  import { jsx as jsx4 } from "react/jsx-runtime";
@@ -7042,6 +7042,7 @@ function clearBookingFieldError(errors, fieldId) {
7042
7042
  function createInitialBookingFlowReducerState(input) {
7043
7043
  const initialData = input.initialData ?? {};
7044
7044
  return {
7045
+ phase: "editing",
7045
7046
  currentStepId: "service-selection",
7046
7047
  selectedServiceId: toOptionalAppointmentServiceId(
7047
7048
  toOptionalString(initialData.serviceId) ?? input.defaultServiceId
@@ -7062,8 +7063,7 @@ function createInitialBookingFlowReducerState(input) {
7062
7063
  ),
7063
7064
  altchaSolution: null,
7064
7065
  validationErrors: createEmptyBookingValidationErrors(),
7065
- feedback: { kind: "none" },
7066
- isSubmitting: false
7066
+ feedback: { kind: "none" }
7067
7067
  };
7068
7068
  }
7069
7069
  function collectInitialFieldValues(initialData) {
@@ -7193,8 +7193,15 @@ function bookingFlowReducer(state, event) {
7193
7193
  case "validation-errors-set":
7194
7194
  return { ...state, validationErrors: event.errors };
7195
7195
  case "feedback-set":
7196
- return { ...state, feedback: event.feedback };
7196
+ return {
7197
+ ...state,
7198
+ phase: event.feedback.kind === "success" ? "completed" : "editing",
7199
+ feedback: event.feedback
7200
+ };
7197
7201
  case "availability-selection-invalidated":
7202
+ if (state.phase !== "editing") {
7203
+ return state;
7204
+ }
7198
7205
  return {
7199
7206
  ...state,
7200
7207
  currentStepId: "datetime-selection",
@@ -7208,11 +7215,11 @@ function bookingFlowReducer(state, event) {
7208
7215
  validationErrors: clearBookingFormError(state.validationErrors)
7209
7216
  };
7210
7217
  case "feedback-cleared":
7211
- return { ...state, feedback: { kind: "none" } };
7218
+ return { ...state, phase: "editing", feedback: { kind: "none" } };
7212
7219
  case "submission-started":
7213
- return { ...state, isSubmitting: true };
7220
+ return { ...state, phase: "submitting" };
7214
7221
  case "submission-finished":
7215
- return { ...state, isSubmitting: false };
7222
+ return state.phase === "submitting" ? { ...state, phase: "editing" } : state;
7216
7223
  case "reset":
7217
7224
  return event.initial;
7218
7225
  default:
@@ -7718,8 +7725,8 @@ function toHeadlessEligibleAppointmentPackage(appointmentPackage) {
7718
7725
  };
7719
7726
  }
7720
7727
  function resolveHeadlessBookingStatus(input) {
7721
- if (input.isSubmitting) return { tag: "submitting" };
7722
- if (input.feedback.kind === "success") {
7728
+ if (input.phase === "submitting") return { tag: "submitting" };
7729
+ if (input.phase === "completed" && input.feedback.kind === "success") {
7723
7730
  return {
7724
7731
  tag: "success",
7725
7732
  resourceName: input.feedback.resourceName
@@ -7901,6 +7908,7 @@ function useHeadlessBookingFlow(options) {
7901
7908
  [availableDates]
7902
7909
  );
7903
7910
  useEffect6(() => {
7911
+ if (state.phase !== "editing") return;
7904
7912
  const canEvaluateDate = availabilityDatesQuery.ok && Boolean(availableDatesLoadedRange) && !isLoadingDates && !datesError;
7905
7913
  const canEvaluateSlot = !state.selectedSlot || availabilitySlotsQuery.ok && hasLoadedSlots && !isLoadingSlots && !slotsError;
7906
7914
  if (!canEvaluateDate || !canEvaluateSlot) return;
@@ -7926,6 +7934,7 @@ function useHeadlessBookingFlow(options) {
7926
7934
  isLoadingSlots,
7927
7935
  slotViews,
7928
7936
  slotsError,
7937
+ state.phase,
7929
7938
  state.selectedDate,
7930
7939
  state.selectedSlot
7931
7940
  ]);
@@ -8086,7 +8095,7 @@ function useHeadlessBookingFlow(options) {
8086
8095
  const submitBooking = useCallback3(
8087
8096
  async (submitOptions) => {
8088
8097
  const latest = latestRef.current;
8089
- if (submittingRef.current || latest.state.isSubmitting) {
8098
+ if (submittingRef.current || latest.state.phase === "submitting") {
8090
8099
  return {
8091
8100
  ok: false,
8092
8101
  reason: "blocked",
@@ -8282,7 +8291,7 @@ function useHeadlessBookingFlow(options) {
8282
8291
  const spamProtectionEnabled = options.spamProtectionEnabled ?? isSpamProtectionEnabled();
8283
8292
  const status = resolveHeadlessBookingStatus({
8284
8293
  feedback: state.feedback,
8285
- isSubmitting: state.isSubmitting
8294
+ phase: state.phase
8286
8295
  });
8287
8296
  const view = resolveHeadlessBookingView({
8288
8297
  form: options.form,
@@ -1,6 +1,7 @@
1
+ import { normalizeCarouselProps, CarouselNodeClient } from './chunk-II7O4XN3.mjs';
2
+ import './chunk-RTZ3JKKX.mjs';
1
3
  import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
2
- import { normalizeCarouselProps, CarouselNodeClient } from './chunk-5IYGMTUE.mjs';
3
- import { defineIslandPropsDecoder } from './chunk-6VGXRE34.mjs';
4
+ import { defineIslandPropsDecoder } from './chunk-7UOSCYY4.mjs';
4
5
  import './chunk-PMAIXMAB.mjs';
5
6
  import { jsx } from 'react/jsx-runtime';
6
7
 
@@ -0,0 +1,18 @@
1
+ import { mountShopBlockIsland, CartClient } from './chunk-PFBX3IQL.mjs';
2
+ import './chunk-BOIHIU7E.mjs';
3
+ import './chunk-II7O4XN3.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-JEZECJ3W.mjs';
7
+ import './chunk-3DCJ45Z2.mjs';
8
+ import './chunk-3PEDD5KJ.mjs';
9
+ import './chunk-M3L3KYYR.mjs';
10
+ import './chunk-N7PBWBWQ.mjs';
11
+ import { defineIslandPropsDecoder } from './chunk-7UOSCYY4.mjs';
12
+ import './chunk-PMAIXMAB.mjs';
13
+
14
+ // src/rendering/islands/enhancers/cart.tsx
15
+ var decode = defineIslandPropsDecoder("cart");
16
+ var enhance = (root, props) => mountShopBlockIsland(root, props, CartClient, "cart");
17
+
18
+ export { decode, enhance };
@@ -0,0 +1,18 @@
1
+ import { mountShopBlockIsland, CheckoutClient } from './chunk-PFBX3IQL.mjs';
2
+ import './chunk-BOIHIU7E.mjs';
3
+ import './chunk-II7O4XN3.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-JEZECJ3W.mjs';
7
+ import './chunk-3DCJ45Z2.mjs';
8
+ import './chunk-3PEDD5KJ.mjs';
9
+ import './chunk-M3L3KYYR.mjs';
10
+ import './chunk-N7PBWBWQ.mjs';
11
+ import { defineIslandPropsDecoder } from './chunk-7UOSCYY4.mjs';
12
+ import './chunk-PMAIXMAB.mjs';
13
+
14
+ // src/rendering/islands/enhancers/checkout.tsx
15
+ var decode = defineIslandPropsDecoder("checkout");
16
+ var enhance = (root, props) => mountShopBlockIsland(root, props, CheckoutClient, "checkout");
17
+
18
+ export { decode, enhance };
@@ -0,0 +1,36 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ // ../blocks/src/system/runtime/shared/components/FieldValidationMessage.tsx
4
+ function getFieldValidationControlProps({
5
+ message,
6
+ messageId,
7
+ describedBy
8
+ }) {
9
+ const hasMessage = Boolean(message);
10
+ const ariaDescribedBy = [describedBy, hasMessage ? messageId : void 0].filter((part) => typeof part === "string" && part.length > 0).join(" ");
11
+ return {
12
+ "aria-invalid": hasMessage ? "true" : void 0,
13
+ "aria-describedby": ariaDescribedBy || void 0
14
+ };
15
+ }
16
+ function FieldValidationMessage({
17
+ id,
18
+ children,
19
+ className,
20
+ live = "assertive"
21
+ }) {
22
+ return /* @__PURE__ */ jsx(
23
+ "p",
24
+ {
25
+ id,
26
+ className,
27
+ "data-field-validation-message": true,
28
+ "data-field-validation-tone": "error",
29
+ role: "alert",
30
+ "aria-live": live === "off" ? void 0 : live,
31
+ children
32
+ }
33
+ );
34
+ }
35
+
36
+ export { FieldValidationMessage, getFieldValidationControlProps };
@@ -0,0 +1,146 @@
1
+ import * as React from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ // ../blocks/src/system/runtime/shared/components/ModalShell.tsx
6
+ var modalBodyScrollLockCount = 0;
7
+ var modalBodyOriginalOverflow = null;
8
+ function lockBodyScroll() {
9
+ if (typeof document === "undefined") {
10
+ return;
11
+ }
12
+ if (modalBodyScrollLockCount === 0) {
13
+ modalBodyOriginalOverflow = document.body.style.overflow;
14
+ document.body.style.overflow = "hidden";
15
+ }
16
+ modalBodyScrollLockCount += 1;
17
+ }
18
+ function unlockBodyScroll() {
19
+ if (typeof document === "undefined" || modalBodyScrollLockCount === 0) {
20
+ return;
21
+ }
22
+ modalBodyScrollLockCount -= 1;
23
+ if (modalBodyScrollLockCount === 0) {
24
+ document.body.style.overflow = modalBodyOriginalOverflow ?? "";
25
+ modalBodyOriginalOverflow = null;
26
+ }
27
+ }
28
+ function ModalShell({
29
+ title,
30
+ titleId,
31
+ onClose,
32
+ children,
33
+ portalRoot,
34
+ portal = false,
35
+ overlayClassName,
36
+ modalClassName,
37
+ renderSrOnlyTitle = false,
38
+ renderHeader,
39
+ headerClassName,
40
+ titleClassName,
41
+ closeButtonClassName,
42
+ closeIcon
43
+ }) {
44
+ const closeButtonRef = React.useRef(null);
45
+ const onCloseRef = React.useRef(onClose);
46
+ onCloseRef.current = onClose;
47
+ React.useEffect(() => {
48
+ closeButtonRef.current?.focus();
49
+ const onKeyDown = (event) => {
50
+ if (event.key === "Escape") {
51
+ onCloseRef.current();
52
+ }
53
+ };
54
+ document.addEventListener("keydown", onKeyDown);
55
+ lockBodyScroll();
56
+ return () => {
57
+ document.removeEventListener("keydown", onKeyDown);
58
+ unlockBodyScroll();
59
+ };
60
+ }, []);
61
+ const srOnlyTitle = renderSrOnlyTitle ? /* @__PURE__ */ jsx(
62
+ "h2",
63
+ {
64
+ id: titleId,
65
+ style: {
66
+ position: "absolute",
67
+ width: 1,
68
+ height: 1,
69
+ padding: 0,
70
+ margin: -1,
71
+ overflow: "hidden",
72
+ clip: "rect(0,0,0,0)",
73
+ whiteSpace: "nowrap",
74
+ border: 0
75
+ },
76
+ children: title
77
+ }
78
+ ) : null;
79
+ const header = renderHeader ? renderHeader({ title, titleId, onClose, closeButtonRef }) : /* @__PURE__ */ jsxs("div", { className: headerClassName, children: [
80
+ !renderSrOnlyTitle ? /* @__PURE__ */ jsx("h3", { className: titleClassName, id: titleId, children: title }) : null,
81
+ /* @__PURE__ */ jsx(
82
+ "button",
83
+ {
84
+ ref: closeButtonRef,
85
+ type: "button",
86
+ className: closeButtonClassName,
87
+ onClick: onClose,
88
+ "aria-label": "Close",
89
+ children: closeIcon ?? "\xD7"
90
+ }
91
+ )
92
+ ] });
93
+ const modal = /* @__PURE__ */ jsx("div", { className: overlayClassName, onClick: onClose, children: /* @__PURE__ */ jsxs(
94
+ "div",
95
+ {
96
+ className: modalClassName,
97
+ onClick: (event) => event.stopPropagation(),
98
+ role: "dialog",
99
+ "aria-modal": "true",
100
+ "aria-labelledby": titleId,
101
+ children: [
102
+ srOnlyTitle,
103
+ header,
104
+ children
105
+ ]
106
+ }
107
+ ) });
108
+ if (!portal) {
109
+ return modal;
110
+ }
111
+ if (typeof document === "undefined") {
112
+ return null;
113
+ }
114
+ if (!portalRoot) {
115
+ return null;
116
+ }
117
+ return createPortal(modal, portalRoot);
118
+ }
119
+
120
+ // ../blocks/src/system/runtime/shared/utils/checkoutRoute.ts
121
+ function resolveDedicatedCheckoutTarget(pathname) {
122
+ const internalPublishedMatch = pathname.match(
123
+ /^\/internal-sites\/([^/]+)\/([^/]+)\/published(?:\/.*)?$/
124
+ );
125
+ if (internalPublishedMatch) {
126
+ const hostKey = internalPublishedMatch[1];
127
+ const siteIdentifier = internalPublishedMatch[2];
128
+ if (hostKey && siteIdentifier) {
129
+ return {
130
+ kind: "internal_published_preview",
131
+ hostKey,
132
+ siteIdentifier
133
+ };
134
+ }
135
+ }
136
+ return { kind: "public" };
137
+ }
138
+ function resolveDedicatedCheckoutPath(pathname) {
139
+ const target = resolveDedicatedCheckoutTarget(pathname);
140
+ if (target.kind === "internal_published_preview") {
141
+ return `/internal-sites/${target.hostKey}/${target.siteIdentifier}/published/checkout`;
142
+ }
143
+ return "/checkout";
144
+ }
145
+
146
+ export { ModalShell, resolveDedicatedCheckoutPath };
@@ -4255,7 +4255,18 @@ function getBookingSuccessMessage(successMessage) {
4255
4255
  return successMessage?.trim() || "Your appointment has been booked! Check your email for confirmation.";
4256
4256
  }
4257
4257
 
4258
- // ../blocks/src/system/runtime/nodes/booking-form.interactive.ts
4258
+ // ../logger/src/noop.ts
4259
+ var noop = () => {
4260
+ };
4261
+ var logger = {
4262
+ debug: noop,
4263
+ info: noop,
4264
+ warn: noop,
4265
+ error: noop,
4266
+ withFields: (_) => logger
4267
+ };
4268
+
4269
+ // ../blocks/src/system/runtime/nodes/booking-runtime-sources.ts
4259
4270
  var bookingFieldOptionSchema = z.object({
4260
4271
  value: z.string(),
4261
4272
  label: z.string()
@@ -4309,6 +4320,8 @@ var bookingSourceFormSchema = z.object({
4309
4320
  createdAt: z.string(),
4310
4321
  updatedAt: z.string()
4311
4322
  });
4323
+
4324
+ // ../blocks/src/system/runtime/nodes/booking-form.interactive.ts
4312
4325
  var blockBookingPaymentTermsAvailabilitySchema = z.union([
4313
4326
  z.object({
4314
4327
  kind: z.literal("available"),
@@ -5228,7 +5241,7 @@ var COLUMN_CLASSES = {
5228
5241
  };
5229
5242
  function getContainerClass(layout, columns) {
5230
5243
  if (layout === "compact") {
5231
- return "rb-flex rb-flex-col rb-gap-2";
5244
+ return "event-listing-compact-container rb-flex rb-flex-col rb-gap-2";
5232
5245
  }
5233
5246
  if (layout === "stack") {
5234
5247
  return "rb-flex rb-flex-col rb-gap-6";
@@ -5359,7 +5372,7 @@ function formatEventPrice(event) {
5359
5372
  }
5360
5373
  function resolveEventCta(event, buttonText) {
5361
5374
  const { isFull: isSoldOut } = getEventAvailability(event);
5362
- const defaultButtonText = event.kind === "course_session" ? "View course" : "View event";
5375
+ const defaultButtonText = event.kind === "course_session" ? "Book course" : "Book now";
5363
5376
  const effectiveButtonText = buttonText ?? defaultButtonText;
5364
5377
  if (isSoldOut) {
5365
5378
  return { label: "Sold out", href: event.path, hidden: true };
@@ -5601,6 +5614,37 @@ function pickReadableTextColor(background) {
5601
5614
  return "rgb(var(--tb-onAccent, 255 255 255))";
5602
5615
  }
5603
5616
  }
5617
+ function BookingOptionCompactRow({
5618
+ option,
5619
+ buttonVariant = "primary"
5620
+ }) {
5621
+ const primaryMeta = option.primaryMeta?.filter((item) => item.length > 0) ?? [];
5622
+ const secondaryMeta = option.secondaryMeta?.filter((item) => item.label.length > 0) ?? [];
5623
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "sm" });
5624
+ return /* @__PURE__ */ jsxs("div", { className: "event-compact-row", children: [
5625
+ /* @__PURE__ */ jsxs("div", { className: "event-compact-row-content", children: [
5626
+ /* @__PURE__ */ jsxs("div", { className: "event-compact-row-top", children: [
5627
+ /* @__PURE__ */ jsx("span", { className: "event-compact-row-title", children: option.title }),
5628
+ primaryMeta.length > 0 && /* @__PURE__ */ jsx("span", { className: "event-compact-row-datetime", children: primaryMeta.join(" \xB7 ") })
5629
+ ] }),
5630
+ /* @__PURE__ */ jsxs("div", { className: "event-compact-row-bottom", children: [
5631
+ secondaryMeta.map((item) => /* @__PURE__ */ jsxs(
5632
+ "span",
5633
+ {
5634
+ className: item.className,
5635
+ children: [
5636
+ item.icon,
5637
+ item.label
5638
+ ]
5639
+ },
5640
+ item.id ?? `${item.className ?? "meta"}:${item.label}`
5641
+ )),
5642
+ option.priceLabel && /* @__PURE__ */ jsx("span", { className: "event-compact-row-price", children: option.priceLabel })
5643
+ ] })
5644
+ ] }),
5645
+ option.action.kind === "status" ? /* @__PURE__ */ jsx("span", { className: "event-compact-row-status", children: option.action.label }) : /* @__PURE__ */ jsx("a", { href: option.action.href, className: `${buttonClass} event-compact-row-cta`, children: option.action.label })
5646
+ ] });
5647
+ }
5604
5648
  var EventCompactRow = ({
5605
5649
  event,
5606
5650
  buttonVariant = "primary",
@@ -5612,28 +5656,31 @@ var EventCompactRow = ({
5612
5656
  const price = formatEventPrice(event);
5613
5657
  const teacherLine = formatEventTeacherLine(event);
5614
5658
  const cta = resolveEventCta(event, buttonText);
5615
- const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "sm" });
5616
- return /* @__PURE__ */ jsxs("div", { className: "event-compact-row", children: [
5617
- /* @__PURE__ */ jsxs("div", { className: "event-compact-row-content", children: [
5618
- /* @__PURE__ */ jsxs("div", { className: "event-compact-row-top", children: [
5619
- /* @__PURE__ */ jsx("span", { className: "event-compact-row-title", children: event.title }),
5620
- /* @__PURE__ */ jsxs("span", { className: "event-compact-row-datetime", children: [
5621
- formattedDate,
5622
- " \xB7 ",
5623
- formattedTime
5624
- ] })
5625
- ] }),
5626
- /* @__PURE__ */ jsxs("div", { className: "event-compact-row-bottom", children: [
5627
- event.venue && /* @__PURE__ */ jsxs("span", { className: "event-compact-row-venue", children: [
5628
- /* @__PURE__ */ jsx(MapPinIcon, { className: "rb-shrink-0" }),
5629
- event.venue.name
5630
- ] }),
5631
- teacherLine && /* @__PURE__ */ jsx("span", { className: "event-compact-row-teacher", children: teacherLine }),
5632
- /* @__PURE__ */ jsx("span", { className: "event-compact-row-price", children: price })
5633
- ] })
5634
- ] }),
5635
- cta.hidden ? /* @__PURE__ */ jsx("span", { className: "event-compact-row-status", children: cta.label }) : /* @__PURE__ */ jsx("a", { href: cta.href, className: `${buttonClass} event-compact-row-cta`, children: cta.label })
5636
- ] });
5659
+ const option = {
5660
+ id: event.occurrenceId ?? event.id,
5661
+ title: event.title,
5662
+ primaryMeta: [formattedDate, formattedTime],
5663
+ secondaryMeta: [
5664
+ ...event.venue ? [
5665
+ {
5666
+ id: "venue",
5667
+ label: event.venue.name,
5668
+ icon: /* @__PURE__ */ jsx(MapPinIcon, { className: "rb-shrink-0" }),
5669
+ className: "event-compact-row-venue"
5670
+ }
5671
+ ] : [],
5672
+ ...teacherLine ? [
5673
+ {
5674
+ id: "teacher",
5675
+ label: teacherLine,
5676
+ className: "event-compact-row-teacher"
5677
+ }
5678
+ ] : []
5679
+ ],
5680
+ priceLabel: price,
5681
+ action: cta.hidden ? { kind: "status", label: cta.label } : { kind: "action", label: cta.label, href: cta.href }
5682
+ };
5683
+ return /* @__PURE__ */ jsx(BookingOptionCompactRow, { buttonVariant, option });
5637
5684
  };
5638
5685
  var EmptyState = ({
5639
5686
  message = "No upcoming events scheduled.",
@@ -5771,7 +5818,7 @@ var eventListingBlockRuntime = defineProgressiveBlockRuntime({
5771
5818
  containerClass: getContainerClass(layout, source.columns ?? "3"),
5772
5819
  cardVariant: source.cardVariant ?? "default",
5773
5820
  buttonVariant: source.buttonVariant ?? "primary",
5774
- buttonText: source.buttonText ?? "View event",
5821
+ buttonText: source.buttonText ?? "Book now",
5775
5822
  showVenue: source.showVenue ?? true,
5776
5823
  showMap: source.showMap ?? true,
5777
5824
  showCapacity: source.showCapacity ?? true,
@@ -5945,7 +5992,7 @@ function buildEventCalendarDisplay(source) {
5945
5992
  ),
5946
5993
  filterVenueId: normalizeEventVenueId(source.filterVenueId),
5947
5994
  buttonVariant: source.buttonVariant ?? "primary",
5948
- buttonText: source.buttonText ?? "View event",
5995
+ buttonText: source.buttonText ?? "Book now",
5949
5996
  showVenue: source.showVenue ?? true,
5950
5997
  showMap: source.showMap ?? true,
5951
5998
  showCapacity: source.showCapacity ?? true,
@@ -6150,7 +6197,7 @@ function buildEventCombinedDisplay(source) {
6150
6197
  showMap: source.showMap ?? true,
6151
6198
  showCapacity: source.showCapacity ?? true,
6152
6199
  buttonVariant: source.buttonVariant ?? "primary",
6153
- buttonText: source.buttonText ?? "View event",
6200
+ buttonText: source.buttonText ?? "Book now",
6154
6201
  emptyMessage: source.emptyMessage ?? "No upcoming events scheduled."
6155
6202
  };
6156
6203
  }
@@ -7614,4 +7661,4 @@ function defineIslandPropsDecoder(kind) {
7614
7661
  };
7615
7662
  }
7616
7663
 
7617
- export { BOOKING_FORM_DATA_RESERVED_KEYS, DateTimeTile, EMPTY_COMMERCE_CART_STATE, EmptyState, EventCard, EventCompactRow, MAX_EVENTS_PER_DAY, MONTH_NAMES, addMonths, assertNever, buildCartDisplay, buildEventCalendarListingRender, buildPassCartItem, buildProductCardDisplay, buildProductCartItem, buildProductDetailDisplay, buildTimetableModel, defineIslandPropsDecoder, deriveBookingFormViewState, err, formatBookingSubmissionPreparationError, formatCalendarTitle, formatCommercePrice, formatCoursePriceAmount, formatCoursePriceDisplay, formatDate, formatDateKey, formatEventDateParts, formatEventPrice, formatEventTeacherLine, formatInterval, formatTime, getBookingRedirectStateFromLocation, getBookingSuccessMessage, getCardOrientation, getContainerClass, getEventAvailability, getMonthCalendarDays, getOrderedDayNames, getShopDisplayForItems, getThreeMonthRange, getWeekCalendarDays, groupEventsByDate, isEventContentType, isToday, normalizeEventBlockKind, normalizeIdList, ok, okWith, parseStoredCommerceCartState, prepareBookingSubmission, productItemKey, reduceCommerceCart, resolveAppointmentCheckoutVerificationState, resolveBookingPaymentStep, resolveBookingSiteId, resolveCoursePricingState, resolveDefaultBookingServiceId, themeButtonClassName, themeColorTokenSchema, toSelectedCollectionOptionKind };
7664
+ export { BOOKING_FORM_DATA_RESERVED_KEYS, DateTimeTile, EMPTY_COMMERCE_CART_STATE, EmptyState, EventCard, EventCompactRow, MAX_EVENTS_PER_DAY, MONTH_NAMES, addMonths, assertNever, buildCartDisplay, buildEventCalendarListingRender, buildPassCartItem, buildProductCardDisplay, buildProductCartItem, buildProductDetailDisplay, buildTimetableModel, defineIslandPropsDecoder, deriveBookingFormViewState, err, formatBookingSubmissionPreparationError, formatCalendarTitle, formatCommercePrice, formatCoursePriceAmount, formatCoursePriceDisplay, formatDate, formatDateKey, formatEventDateParts, formatEventPrice, formatEventTeacherLine, formatInterval, formatTime, getBookingRedirectStateFromLocation, getBookingSuccessMessage, getCardOrientation, getContainerClass, getEventAvailability, getMonthCalendarDays, getOrderedDayNames, getShopDisplayForItems, getThreeMonthRange, getWeekCalendarDays, groupEventsByDate, isEventContentType, isToday, logger, normalizeEventBlockKind, normalizeIdList, ok, okWith, parseStoredCommerceCartState, prepareBookingSubmission, productItemKey, reduceCommerceCart, resolveAppointmentCheckoutVerificationState, resolveBookingPaymentStep, resolveBookingSiteId, resolveCoursePricingState, resolveDefaultBookingServiceId, themeButtonClassName, toSelectedCollectionOptionKind };
@@ -0,0 +1,106 @@
1
+ import { EMPTY_COMMERCE_CART_STATE, parseStoredCommerceCartState, reduceCommerceCart, buildPassCartItem } from './chunk-7UOSCYY4.mjs';
2
+ import * as React from 'react';
3
+
4
+ var EMPTY_STATE = EMPTY_COMMERCE_CART_STATE;
5
+ var stores = /* @__PURE__ */ new Map();
6
+ function storageKey(siteId) {
7
+ return `riverbank:shop-cart:${siteId}`;
8
+ }
9
+ var CommerceCartStore = class {
10
+ constructor(siteId) {
11
+ this.siteId = siteId;
12
+ this.listeners = /* @__PURE__ */ new Set();
13
+ this.state = typeof window === "undefined" ? EMPTY_STATE : parseStoredCommerceCartState(window.localStorage.getItem(storageKey(siteId)));
14
+ }
15
+ subscribe(listener) {
16
+ this.listeners.add(listener);
17
+ return () => {
18
+ this.listeners.delete(listener);
19
+ };
20
+ }
21
+ getSnapshot() {
22
+ return this.state;
23
+ }
24
+ addProduct(input) {
25
+ this.setState(
26
+ reduceCommerceCart(this.state, {
27
+ type: "add_product",
28
+ item: {
29
+ key: input.key,
30
+ kind: "product",
31
+ productId: input.productId,
32
+ ...input.variantId ? { variantId: input.variantId } : {},
33
+ title: input.title,
34
+ variantTitle: input.variantTitle ?? null,
35
+ quantity: input.quantity ?? 1,
36
+ unitPriceCents: input.unitPriceCents,
37
+ currency: input.currency,
38
+ imageUrl: input.imageUrl ?? null,
39
+ soldOut: input.soldOut ?? false
40
+ }
41
+ })
42
+ );
43
+ }
44
+ addPass(input) {
45
+ this.setState(
46
+ reduceCommerceCart(this.state, {
47
+ type: "add_pass",
48
+ item: buildPassCartItem(input)
49
+ })
50
+ );
51
+ }
52
+ updateQuantity(itemKey, quantity) {
53
+ this.setState(reduceCommerceCart(this.state, {
54
+ type: "update_quantity",
55
+ itemKey,
56
+ quantity
57
+ }));
58
+ }
59
+ removeItem(itemKey) {
60
+ this.setState(reduceCommerceCart(this.state, {
61
+ type: "remove_item",
62
+ itemKey
63
+ }));
64
+ }
65
+ clear() {
66
+ this.setState(reduceCommerceCart(this.state, { type: "clear" }));
67
+ }
68
+ setState(nextState) {
69
+ this.state = nextState;
70
+ if (typeof window !== "undefined") {
71
+ window.localStorage.setItem(storageKey(this.siteId), JSON.stringify(nextState));
72
+ }
73
+ for (const listener of this.listeners) {
74
+ listener();
75
+ }
76
+ }
77
+ };
78
+ function getStore(siteId) {
79
+ const existing = stores.get(siteId);
80
+ if (existing) return existing;
81
+ const next = new CommerceCartStore(siteId);
82
+ stores.set(siteId, next);
83
+ return next;
84
+ }
85
+ function addPassToCommerceCart(siteId, input) {
86
+ getStore(siteId ?? "unknown").addPass(input);
87
+ }
88
+ function useCommerceCart(siteId) {
89
+ const effectiveSiteId = siteId ?? "unknown";
90
+ const store = React.useMemo(() => getStore(effectiveSiteId), [effectiveSiteId]);
91
+ const state = React.useSyncExternalStore(
92
+ (listener) => store.subscribe(listener),
93
+ () => store.getSnapshot(),
94
+ () => EMPTY_STATE
95
+ );
96
+ return {
97
+ items: state.items,
98
+ addProduct: store.addProduct.bind(store),
99
+ addPass: store.addPass.bind(store),
100
+ updateQuantity: store.updateQuantity.bind(store),
101
+ removeItem: store.removeItem.bind(store),
102
+ clear: store.clear.bind(store)
103
+ };
104
+ }
105
+
106
+ export { addPassToCommerceCart, useCommerceCart };