@riverbankcms/sdk 0.72.0 → 0.75.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 (146) hide show
  1. package/README.md +1 -1
  2. package/dist/{PreviewEditorSidebar-44T64SAR.mjs → PreviewEditorSidebar-U2IHCBYN.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-4WKHZTXW.mjs → PreviewEditorUI-ZGH2RQNP.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-MTUGBTLQ.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +10 -10
  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/publicExperienceEndpoints.d.ts +2 -1
  10. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +4 -1
  11. package/dist/_dts/blocks/src/client/booking-form.d.ts +2 -0
  12. package/dist/_dts/blocks/src/client/carousel.d.ts +1 -0
  13. package/dist/_dts/blocks/src/client/course-registration.d.ts +2 -0
  14. package/dist/_dts/blocks/src/client/events.d.ts +4 -0
  15. package/dist/_dts/blocks/src/client/form.d.ts +2 -0
  16. package/dist/_dts/blocks/src/client/header.d.ts +1 -0
  17. package/dist/_dts/blocks/src/client/location-map.d.ts +1 -0
  18. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +2 -0
  19. package/dist/_dts/blocks/src/client/shop.d.ts +6 -0
  20. package/dist/_dts/blocks/src/lib/video.d.ts +2 -0
  21. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +21 -1
  22. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +6 -6
  23. package/dist/_dts/blocks/src/system/node/fragments/backgroundLayer.d.ts +15 -1
  24. package/dist/_dts/blocks/src/system/node/fragments/styledSection.d.ts +11 -0
  25. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +1 -0
  26. package/dist/_dts/blocks/src/system/runtime/header/enhanceHeaderSection.d.ts +13 -0
  27. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +3 -2
  28. package/dist/_dts/blocks/src/system/runtime/nodes/events/index.d.ts +3 -0
  29. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.client.d.ts +1 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.server.d.ts +1 -0
  31. package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +6 -0
  32. package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +5 -0
  33. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +12 -2
  34. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -0
  35. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +2 -2
  36. package/dist/_dts/sdk/src/rendering/islands/deferredVideoEmbeds.d.ts +2 -0
  37. package/dist/_dts/sdk/src/rendering/islands/enhancers/accordion.d.ts +1 -0
  38. package/dist/_dts/sdk/src/rendering/islands/enhancers/bookingForm.d.ts +1 -0
  39. package/dist/_dts/sdk/src/rendering/islands/enhancers/carousel.d.ts +1 -0
  40. package/dist/_dts/sdk/src/rendering/islands/enhancers/cart.d.ts +1 -0
  41. package/dist/_dts/sdk/src/rendering/islands/enhancers/checkout.d.ts +1 -0
  42. package/dist/_dts/sdk/src/rendering/islands/enhancers/courseRegistration.d.ts +1 -0
  43. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventCalendar.d.ts +1 -0
  44. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventCombined.d.ts +1 -0
  45. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventDetails.d.ts +1 -0
  46. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventListing.d.ts +1 -0
  47. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventRegistration.d.ts +1 -0
  48. package/dist/_dts/sdk/src/rendering/islands/enhancers/form.d.ts +1 -0
  49. package/dist/_dts/sdk/src/rendering/islands/enhancers/headerSection.d.ts +1 -0
  50. package/dist/_dts/sdk/src/rendering/islands/enhancers/locationMap.d.ts +1 -0
  51. package/dist/_dts/sdk/src/rendering/islands/enhancers/newsletterForm.d.ts +1 -0
  52. package/dist/_dts/sdk/src/rendering/islands/enhancers/productDetail.d.ts +1 -0
  53. package/dist/_dts/sdk/src/rendering/islands/enhancers/productList.d.ts +1 -0
  54. package/dist/_dts/sdk/src/rendering/islands/enhancers/shop.d.ts +1 -0
  55. package/dist/_dts/sdk/src/rendering/islands/hydrateBlocksIslands.d.ts +2 -2
  56. package/dist/_dts/sdk/src/rendering/islands/propsDecoder.d.ts +7 -0
  57. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +9 -0
  58. package/dist/_dts/sdk/src/rendering/server.d.ts +3 -0
  59. package/dist/_dts/sdk/src/version.d.ts +1 -1
  60. package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
  61. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +7 -7
  62. package/dist/_dts/theme-core/src/buttons/types.d.ts +20 -20
  63. package/dist/_dts/theme-core/src/cards/types.d.ts +2 -2
  64. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  65. package/dist/_dts/theme-core/src/header/navDropdownSizing.d.ts +7 -0
  66. package/dist/_dts/theme-core/src/inputs/types.d.ts +3 -3
  67. package/dist/_dts/theme-core/src/interactive/baseSchema.d.ts +1 -1
  68. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +156 -156
  69. package/dist/_dts/theme-core/src/navigation/types.d.ts +1 -1
  70. package/dist/_dts/theme-core/src/palette/variants/types.d.ts +4 -4
  71. package/dist/_dts/theme-core/src/schema.d.ts +178 -178
  72. package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +2 -2
  73. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +8 -8
  74. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +5 -5
  75. package/dist/_dts/theme-core/src/tokens/themeColorTokens.d.ts +2 -2
  76. package/dist/{chunk-G4NLITC2.mjs → chunk-BGMNDF6T.mjs} +7 -7
  77. package/dist/{chunk-3YNCQG5N.mjs → chunk-GFE74WRD.mjs} +457 -98
  78. package/dist/{chunk-HV745JYE.mjs → chunk-RWXQBRQZ.mjs} +1 -1
  79. package/dist/{chunk-7RX72SK2.mjs → chunk-VX7B5VAC.mjs} +36 -25
  80. package/dist/{chunk-YRJKZEQ3.mjs → chunk-Z7JLNTJR.mjs} +1 -1
  81. package/dist/{chunk-KWQPAJYS.mjs → chunk-ZSHFGFUG.mjs} +2 -2
  82. package/dist/cli/index.mjs +3498 -3826
  83. package/dist/client/accordion-T2UD2ZTH.mjs +120 -0
  84. package/dist/client/altcha-LIGLPZS5.mjs +2755 -0
  85. package/dist/client/bookingForm-GUP75FKN.mjs +3022 -0
  86. package/dist/client/bookings.mjs +32 -10
  87. package/dist/client/carousel-2NQA6V57.mjs +47 -0
  88. package/dist/client/cart-5TFIAFDS.mjs +18 -0
  89. package/dist/client/checkout-TP4WAHZE.mjs +18 -0
  90. package/dist/client/chunk-2PHQZ666.mjs +383 -0
  91. package/dist/client/chunk-3DCJ45Z2.mjs +36 -0
  92. package/dist/client/chunk-3PEDD5KJ.mjs +146 -0
  93. package/dist/client/chunk-CY2ZTSE5.mjs +204 -0
  94. package/dist/client/chunk-F7LHOKEH.mjs +146 -0
  95. package/dist/client/chunk-FU2QRZMX.mjs +7617 -0
  96. package/dist/client/chunk-I2MMZO53.mjs +6 -0
  97. package/dist/client/chunk-II7O4XN3.mjs +2206 -0
  98. package/dist/client/chunk-M3L3KYYR.mjs +1181 -0
  99. package/dist/client/chunk-N7PBWBWQ.mjs +26 -0
  100. package/dist/client/chunk-NWOUL6JY.mjs +1378 -0
  101. package/dist/client/chunk-OJPZEZU2.mjs +31 -0
  102. package/dist/client/chunk-PMAIXMAB.mjs +1960 -0
  103. package/dist/client/chunk-RTZ3JKKX.mjs +178 -0
  104. package/dist/client/chunk-TQ5MSPDX.mjs +74 -0
  105. package/dist/client/chunk-VUAOE3AG.mjs +5592 -0
  106. package/dist/client/chunk-WJXXNDSE.mjs +245 -0
  107. package/dist/client/chunk-YLMKMCSJ.mjs +86 -0
  108. package/dist/client/chunk-ZLMS67RR.mjs +106 -0
  109. package/dist/client/client.mjs +51865 -52071
  110. package/dist/client/courseRegistration-5DPU6PDY.mjs +1737 -0
  111. package/dist/client/eventCalendar-F3GZGTEF.mjs +40 -0
  112. package/dist/client/eventCombined-BQOB6QMY.mjs +37 -0
  113. package/dist/client/eventDetails-PEM2EJWE.mjs +25 -0
  114. package/dist/client/eventListing-YMIQPVME.mjs +40 -0
  115. package/dist/client/eventRegistration-4I6ZNDUF.mjs +40 -0
  116. package/dist/client/form-ZJVAYZ6G.mjs +300 -0
  117. package/dist/client/headerSection-TOT5MGTF.mjs +729 -0
  118. package/dist/client/hooks.mjs +91 -42
  119. package/dist/client/locationMap-J66NZREU.mjs +227 -0
  120. package/dist/client/newsletterForm-ET2XUMRO.mjs +208 -0
  121. package/dist/client/productDetail-C2XIH7C5.mjs +18 -0
  122. package/dist/client/productList-T2AZLFTP.mjs +18 -0
  123. package/dist/client/rendering/client.mjs +12796 -18295
  124. package/dist/client/rendering/islands.mjs +108 -44022
  125. package/dist/client/rendering.mjs +45141 -45346
  126. package/dist/client/shop-UZ6IUZXD.mjs +20 -0
  127. package/dist/preview-next/before-render.mjs +37 -25
  128. package/dist/preview-next/client/runtime.mjs +5 -5
  129. package/dist/preview-next/middleware.mjs +37 -25
  130. package/dist/{sdk-runtime-NGDWSWOS.mjs → sdk-runtime-JCUQM63Y.mjs} +6 -6
  131. package/dist/server/components.mjs +472 -276
  132. package/dist/server/config-validation.mjs +91 -42
  133. package/dist/server/config.mjs +91 -42
  134. package/dist/server/data.mjs +91 -42
  135. package/dist/server/index.mjs +45 -33
  136. package/dist/server/next.mjs +468 -272
  137. package/dist/server/page-converter.mjs +41 -17
  138. package/dist/server/prebuild.mjs +1 -1
  139. package/dist/server/rendering/server.mjs +556 -275
  140. package/dist/server/rendering.mjs +474 -278
  141. package/dist/server/routing.mjs +99 -43
  142. package/dist/server/server.mjs +92 -43
  143. package/dist/server/theme-bridge.mjs +29 -0
  144. package/dist/styles/index.css +16 -0
  145. package/package.json +2 -1
  146. package/dist/SdkPreviewModeRuntime-FO6V7YVY.mjs +0 -8
@@ -0,0 +1,40 @@
1
+ import { EventCalendarClient } from './chunk-VUAOE3AG.mjs';
2
+ import './chunk-F7LHOKEH.mjs';
3
+ import './chunk-CY2ZTSE5.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-WJXXNDSE.mjs';
7
+ import './chunk-TQ5MSPDX.mjs';
8
+ import './chunk-2PHQZ666.mjs';
9
+ import './chunk-3DCJ45Z2.mjs';
10
+ import './chunk-3PEDD5KJ.mjs';
11
+ import './chunk-YLMKMCSJ.mjs';
12
+ import { BlockApiProvider } from './chunk-M3L3KYYR.mjs';
13
+ import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
14
+ import { defineIslandPropsDecoder } from './chunk-FU2QRZMX.mjs';
15
+ import './chunk-PMAIXMAB.mjs';
16
+ import { jsx } from 'react/jsx-runtime';
17
+
18
+ var decode = defineIslandPropsDecoder("event-calendar");
19
+ var enhance = (root, props) => {
20
+ const { siteId, apiBaseUrl, stage } = props;
21
+ if (!siteId) {
22
+ throw new Error("[sdk:islands] event-calendar requires siteId");
23
+ }
24
+ if (!apiBaseUrl) {
25
+ throw new Error("[sdk:islands] event-calendar requires apiBaseUrl");
26
+ }
27
+ const apiConfig = {
28
+ baseUrl: apiBaseUrl,
29
+ auth: { type: "none" },
30
+ siteId,
31
+ isPreview: stage === "preview"
32
+ };
33
+ return mountReactIsland(root, ({ root: reactRoot }) => {
34
+ reactRoot.render(
35
+ /* @__PURE__ */ jsx(BlockApiProvider, { config: apiConfig, children: /* @__PURE__ */ jsx(EventCalendarClient, { ...props }) })
36
+ );
37
+ });
38
+ };
39
+
40
+ export { decode, enhance };
@@ -0,0 +1,37 @@
1
+ import { EventCombinedIslandClient } from './chunk-VUAOE3AG.mjs';
2
+ import './chunk-F7LHOKEH.mjs';
3
+ import './chunk-CY2ZTSE5.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-WJXXNDSE.mjs';
7
+ import './chunk-TQ5MSPDX.mjs';
8
+ import './chunk-2PHQZ666.mjs';
9
+ import './chunk-3DCJ45Z2.mjs';
10
+ import './chunk-3PEDD5KJ.mjs';
11
+ import './chunk-YLMKMCSJ.mjs';
12
+ import { BlockApiProvider } from './chunk-M3L3KYYR.mjs';
13
+ import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
14
+ import { defineIslandPropsDecoder } from './chunk-FU2QRZMX.mjs';
15
+ import './chunk-PMAIXMAB.mjs';
16
+ import { jsx } from 'react/jsx-runtime';
17
+
18
+ var decode = defineIslandPropsDecoder("event-combined");
19
+ var enhance = (root, props) => {
20
+ const { siteId, apiBaseUrl, stage } = props;
21
+ if (!apiBaseUrl) {
22
+ throw new Error("[sdk:islands] event-combined requires apiBaseUrl");
23
+ }
24
+ const apiConfig = {
25
+ baseUrl: apiBaseUrl,
26
+ auth: { type: "none" },
27
+ siteId,
28
+ isPreview: stage === "preview"
29
+ };
30
+ return mountReactIsland(root, ({ root: reactRoot }) => {
31
+ reactRoot.render(
32
+ /* @__PURE__ */ jsx(BlockApiProvider, { config: apiConfig, children: /* @__PURE__ */ jsx(EventCombinedIslandClient, { ...props }) })
33
+ );
34
+ });
35
+ };
36
+
37
+ export { decode, enhance };
@@ -0,0 +1,25 @@
1
+ import { EventDetailsIslandClient } from './chunk-VUAOE3AG.mjs';
2
+ import './chunk-F7LHOKEH.mjs';
3
+ import './chunk-CY2ZTSE5.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-WJXXNDSE.mjs';
7
+ import './chunk-TQ5MSPDX.mjs';
8
+ import './chunk-2PHQZ666.mjs';
9
+ import './chunk-3DCJ45Z2.mjs';
10
+ import './chunk-3PEDD5KJ.mjs';
11
+ import './chunk-YLMKMCSJ.mjs';
12
+ import './chunk-M3L3KYYR.mjs';
13
+ import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
14
+ import { defineIslandPropsDecoder } from './chunk-FU2QRZMX.mjs';
15
+ import './chunk-PMAIXMAB.mjs';
16
+ import { jsx } from 'react/jsx-runtime';
17
+
18
+ var decode = defineIslandPropsDecoder("event-details");
19
+ var enhance = (root, props) => {
20
+ return mountReactIsland(root, ({ root: reactRoot }) => {
21
+ reactRoot.render(/* @__PURE__ */ jsx(EventDetailsIslandClient, { ...props }));
22
+ });
23
+ };
24
+
25
+ export { decode, enhance };
@@ -0,0 +1,40 @@
1
+ import { EventListingClient } from './chunk-VUAOE3AG.mjs';
2
+ import './chunk-F7LHOKEH.mjs';
3
+ import './chunk-CY2ZTSE5.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-WJXXNDSE.mjs';
7
+ import './chunk-TQ5MSPDX.mjs';
8
+ import './chunk-2PHQZ666.mjs';
9
+ import './chunk-3DCJ45Z2.mjs';
10
+ import './chunk-3PEDD5KJ.mjs';
11
+ import './chunk-YLMKMCSJ.mjs';
12
+ import { BlockApiProvider } from './chunk-M3L3KYYR.mjs';
13
+ import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
14
+ import { defineIslandPropsDecoder } from './chunk-FU2QRZMX.mjs';
15
+ import './chunk-PMAIXMAB.mjs';
16
+ import { jsx } from 'react/jsx-runtime';
17
+
18
+ var decode = defineIslandPropsDecoder("event-listing");
19
+ var enhance = (root, props) => {
20
+ const { siteId, apiBaseUrl, stage } = props;
21
+ if (!siteId) {
22
+ throw new Error("[sdk:islands] event-listing requires siteId");
23
+ }
24
+ if (!apiBaseUrl) {
25
+ throw new Error("[sdk:islands] event-listing requires apiBaseUrl");
26
+ }
27
+ const apiConfig = {
28
+ baseUrl: apiBaseUrl,
29
+ auth: { type: "none" },
30
+ siteId,
31
+ isPreview: stage === "preview"
32
+ };
33
+ return mountReactIsland(root, ({ root: reactRoot }) => {
34
+ reactRoot.render(
35
+ /* @__PURE__ */ jsx(BlockApiProvider, { config: apiConfig, children: /* @__PURE__ */ jsx(EventListingClient, { ...props }) })
36
+ );
37
+ });
38
+ };
39
+
40
+ export { decode, enhance };
@@ -0,0 +1,40 @@
1
+ import { EventRegistrationIslandClient } from './chunk-VUAOE3AG.mjs';
2
+ import './chunk-F7LHOKEH.mjs';
3
+ import './chunk-CY2ZTSE5.mjs';
4
+ import './chunk-I2MMZO53.mjs';
5
+ import './chunk-RTZ3JKKX.mjs';
6
+ import './chunk-WJXXNDSE.mjs';
7
+ import './chunk-TQ5MSPDX.mjs';
8
+ import './chunk-2PHQZ666.mjs';
9
+ import './chunk-3DCJ45Z2.mjs';
10
+ import './chunk-3PEDD5KJ.mjs';
11
+ import './chunk-YLMKMCSJ.mjs';
12
+ import { BlockApiProvider } from './chunk-M3L3KYYR.mjs';
13
+ import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
14
+ import { defineIslandPropsDecoder } from './chunk-FU2QRZMX.mjs';
15
+ import './chunk-PMAIXMAB.mjs';
16
+ import { jsx } from 'react/jsx-runtime';
17
+
18
+ var decode = defineIslandPropsDecoder("event-registration");
19
+ var enhance = (root, props) => {
20
+ const { siteId, apiBaseUrl, stage, portalToken } = props;
21
+ if (!siteId) {
22
+ throw new Error("[sdk:islands] event-registration requires siteId");
23
+ }
24
+ if (!apiBaseUrl) {
25
+ throw new Error("[sdk:islands] event-registration requires apiBaseUrl");
26
+ }
27
+ const apiConfig = {
28
+ baseUrl: apiBaseUrl,
29
+ auth: portalToken ? { type: "bearer", token: portalToken } : { type: "none" },
30
+ siteId,
31
+ isPreview: stage === "preview"
32
+ };
33
+ return mountReactIsland(root, ({ root: reactRoot }) => {
34
+ reactRoot.render(
35
+ /* @__PURE__ */ jsx(BlockApiProvider, { config: apiConfig, children: /* @__PURE__ */ jsx(EventRegistrationIslandClient, { ...props }) })
36
+ );
37
+ });
38
+ };
39
+
40
+ export { decode, enhance };
@@ -0,0 +1,300 @@
1
+ "use client";
2
+ import { isSpamProtectionEnabled, AltchaWidget, getChallengeUrl } from './chunk-YLMKMCSJ.mjs';
3
+ import { BlockApiProvider, FeedbackMessage, useBlockApi } from './chunk-M3L3KYYR.mjs';
4
+ import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
5
+ import { defineIslandPropsDecoder, themeButtonClassName, assertNever, err, ok } from './chunk-FU2QRZMX.mjs';
6
+ import { clsx_default } from './chunk-PMAIXMAB.mjs';
7
+ import { useState, useReducer, useRef } from 'react';
8
+ import { jsx, jsxs } from 'react/jsx-runtime';
9
+
10
+ // ../blocks/src/system/runtime/hooks/useFormSubmission.state.ts
11
+ var initialFormSubmissionState = { tag: "idle" };
12
+ function formSubmissionReducer(_state, action) {
13
+ switch (action.type) {
14
+ case "submission-started":
15
+ return { tag: "submitting" };
16
+ case "submission-succeeded":
17
+ return { tag: "succeeded" };
18
+ case "submission-failed":
19
+ return { tag: "failed", message: action.message };
20
+ default:
21
+ return assertNever(action);
22
+ }
23
+ }
24
+
25
+ // ../blocks/src/system/runtime/hooks/useFormSubmission.ts
26
+ function useFormSubmission() {
27
+ const api = useBlockApi();
28
+ const [state, dispatch] = useReducer(
29
+ formSubmissionReducer,
30
+ initialFormSubmissionState
31
+ );
32
+ const stateRef = useRef(state);
33
+ stateRef.current = state;
34
+ const submit = async (data) => {
35
+ if (stateRef.current.tag === "submitting") {
36
+ return err("Already submitting");
37
+ }
38
+ stateRef.current = { tag: "submitting" };
39
+ dispatch({ type: "submission-started" });
40
+ try {
41
+ await api.submitForm(data);
42
+ stateRef.current = { tag: "succeeded" };
43
+ dispatch({ type: "submission-succeeded" });
44
+ return ok();
45
+ } catch (error) {
46
+ const message = error instanceof Error ? error.message : "Failed to submit form";
47
+ stateRef.current = { tag: "failed", message };
48
+ dispatch({ type: "submission-failed", message });
49
+ return err(message);
50
+ }
51
+ };
52
+ return { submit, state };
53
+ }
54
+ var FormNodeClient = ({
55
+ render
56
+ }) => {
57
+ const form = render.display.form;
58
+ const { submit, state } = useFormSubmission();
59
+ const [altchaSolution, setAltchaSolution] = useState(null);
60
+ const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
61
+ if (!form) {
62
+ return /* @__PURE__ */ jsx(
63
+ FeedbackMessage,
64
+ {
65
+ tone: "warning",
66
+ className: clsx_default("fb-empty", render.display.className ?? void 0),
67
+ role: "status",
68
+ children: "Missing or unknown form."
69
+ }
70
+ );
71
+ }
72
+ const groups = render.display.groups;
73
+ const renderField = (field) => {
74
+ const inputId = `f_${field.id}`;
75
+ const label = String(field.label ?? field.id);
76
+ const required = Boolean(field.required);
77
+ const type = String(field.type ?? "text");
78
+ if (type === "textarea") {
79
+ return /* @__PURE__ */ jsxs("div", { className: "fb-field", children: [
80
+ /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "form-label", children: label }),
81
+ /* @__PURE__ */ jsx(
82
+ "textarea",
83
+ {
84
+ id: inputId,
85
+ name: field.id,
86
+ required,
87
+ placeholder: field.placeholder,
88
+ rows: field.rows,
89
+ className: "form-textarea"
90
+ }
91
+ )
92
+ ] }, field.id);
93
+ }
94
+ if (type === "select") {
95
+ const options = field.options ?? [];
96
+ const multiple = Boolean(field.multiple);
97
+ return /* @__PURE__ */ jsxs("div", { className: "fb-field", children: [
98
+ /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "form-label", children: label }),
99
+ /* @__PURE__ */ jsxs(
100
+ "select",
101
+ {
102
+ id: inputId,
103
+ name: field.id,
104
+ multiple,
105
+ required,
106
+ className: "form-select",
107
+ children: [
108
+ !multiple && /* @__PURE__ */ jsx("option", { value: "", children: "Select\u2026" }),
109
+ options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
110
+ ]
111
+ }
112
+ )
113
+ ] }, field.id);
114
+ }
115
+ if (type === "radio") {
116
+ const options = field.options ?? [];
117
+ return /* @__PURE__ */ jsxs("fieldset", { className: "fb-fieldset", children: [
118
+ /* @__PURE__ */ jsx("legend", { className: "form-label", children: label }),
119
+ options.map((opt) => /* @__PURE__ */ jsxs("label", { className: "fb-inline form-label", children: [
120
+ /* @__PURE__ */ jsx("input", { type: "radio", name: field.id, value: opt.value, required, className: "form-radio" }),
121
+ /* @__PURE__ */ jsx("span", { children: opt.label })
122
+ ] }, opt.value))
123
+ ] }, field.id);
124
+ }
125
+ if (type === "checkbox" || type === "consent") {
126
+ return /* @__PURE__ */ jsxs("label", { className: "fb-inline form-label", children: [
127
+ /* @__PURE__ */ jsx("input", { type: "checkbox", name: field.id, required, className: "form-checkbox" }),
128
+ /* @__PURE__ */ jsx("span", { children: label })
129
+ ] }, field.id);
130
+ }
131
+ const inputType = type === "email" || type === "url" || type === "tel" || type === "number" ? type : "text";
132
+ const extra = {};
133
+ if (inputType === "text" || inputType === "email" || inputType === "url" || inputType === "tel") {
134
+ if (typeof field.minLength === "number") extra.minLength = field.minLength;
135
+ if (typeof field.maxLength === "number") extra.maxLength = field.maxLength;
136
+ if (typeof field.pattern === "string" && field.pattern) extra.pattern = field.pattern;
137
+ }
138
+ if (inputType === "number") {
139
+ if (typeof field.min === "number") extra.min = field.min;
140
+ if (typeof field.max === "number") extra.max = field.max;
141
+ }
142
+ return /* @__PURE__ */ jsxs("div", { className: "fb-field", children: [
143
+ /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "form-label", children: label }),
144
+ /* @__PURE__ */ jsx(
145
+ "input",
146
+ {
147
+ id: inputId,
148
+ name: field.id,
149
+ type: inputType,
150
+ required,
151
+ placeholder: field.placeholder,
152
+ ...extra,
153
+ className: "form-input"
154
+ }
155
+ )
156
+ ] }, field.id);
157
+ };
158
+ const handleSubmit = async (e) => {
159
+ e.preventDefault();
160
+ const formData = new FormData(e.currentTarget);
161
+ const honeypot = formData.get("company");
162
+ if (honeypot?.trim()) return;
163
+ const data = {};
164
+ for (const [key, fieldValue] of formData.entries()) {
165
+ if (key === "company" || key === "altcha-solution") continue;
166
+ if (key in data) {
167
+ const existing = data[key];
168
+ data[key] = Array.isArray(existing) ? [...existing, fieldValue] : [existing, fieldValue];
169
+ } else {
170
+ data[key] = fieldValue;
171
+ }
172
+ }
173
+ await submit({
174
+ formId: form.id,
175
+ data,
176
+ meta: {
177
+ honeypot,
178
+ altchaSolution,
179
+ referer: typeof window !== "undefined" ? window.location.href : void 0,
180
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
181
+ }
182
+ });
183
+ };
184
+ if (state.tag === "succeeded") {
185
+ return /* @__PURE__ */ jsx(
186
+ FeedbackMessage,
187
+ {
188
+ tone: "success",
189
+ className: clsx_default("fb-success", render.display.className ?? void 0),
190
+ role: "status",
191
+ children: render.display.successMessage?.trim() || "Thanks \u2014 we received your submission."
192
+ }
193
+ );
194
+ }
195
+ const errorBanner = state.tag === "failed" ? /* @__PURE__ */ jsx(FeedbackMessage, { tone: "error", className: "fb-error", role: "alert", children: state.message }) : null;
196
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: clsx_default("fb-form", render.display.className ?? void 0), children: [
197
+ errorBanner,
198
+ /* @__PURE__ */ jsx("input", { type: "hidden", name: "form_id", value: render.display.formId ?? "" }),
199
+ /* @__PURE__ */ jsx("input", { type: "text", name: "company", className: "hidden", tabIndex: -1, autoComplete: "off" }),
200
+ groups.map((group) => {
201
+ if (group.type === "row") {
202
+ return /* @__PURE__ */ jsx("div", { className: "fb-row fb-row-2", children: group.fields.map(renderField) }, group.key);
203
+ }
204
+ return renderField(group.field);
205
+ }),
206
+ showSpamProtection && /* @__PURE__ */ jsx(AltchaWidget, { challengeUrl: getChallengeUrl(), onSolutionChange: setAltchaSolution }),
207
+ /* @__PURE__ */ jsx("div", { className: "fb-actions", children: /* @__PURE__ */ jsx("div", { className: "fb-actions-inner", children: /* @__PURE__ */ jsx(
208
+ "button",
209
+ {
210
+ type: "submit",
211
+ className: themeButtonClassName({
212
+ variant: "primary",
213
+ size: "md",
214
+ extraClassName: "rb-w-full rb-sm-w-auto"
215
+ }),
216
+ disabled: state.tag === "submitting",
217
+ children: state.tag === "submitting" ? "Submitting..." : render.display.submitLabel
218
+ }
219
+ ) }) })
220
+ ] });
221
+ };
222
+ var decode = defineIslandPropsDecoder("form");
223
+ function snapshotFormValues(form) {
224
+ if (!form) return [];
225
+ const snapshots = [];
226
+ const elements = Array.from(form.elements);
227
+ for (const el of elements) {
228
+ if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement)) {
229
+ continue;
230
+ }
231
+ const name = el.name;
232
+ if (!name) continue;
233
+ if (el instanceof HTMLSelectElement && el.multiple) {
234
+ const selected = Array.from(el.selectedOptions).map((o) => o.value);
235
+ snapshots.push({ kind: "select-multiple", name, values: selected });
236
+ continue;
237
+ }
238
+ if (el instanceof HTMLInputElement && (el.type === "checkbox" || el.type === "radio")) {
239
+ snapshots.push({ kind: "checked", name, value: el.value, checked: el.checked });
240
+ continue;
241
+ }
242
+ snapshots.push({ kind: "value", name, value: el.value });
243
+ }
244
+ return snapshots;
245
+ }
246
+ function applySnapshots(form, snapshots) {
247
+ if (!form) return;
248
+ for (const snapshot of snapshots) {
249
+ if (snapshot.kind === "select-multiple") {
250
+ const el2 = form.elements.namedItem(snapshot.name);
251
+ if (!(el2 instanceof HTMLSelectElement) || !el2.multiple) continue;
252
+ const selected = new Set(snapshot.values);
253
+ Array.from(el2.options).forEach((opt) => {
254
+ opt.selected = selected.has(opt.value);
255
+ });
256
+ continue;
257
+ }
258
+ const el = form.elements.namedItem(snapshot.name);
259
+ if (snapshot.kind === "checked") {
260
+ if (el instanceof RadioNodeList) {
261
+ const inputs = Array.from(el).filter((i) => i instanceof HTMLInputElement);
262
+ const match = inputs.find((i) => i.value === snapshot.value);
263
+ if (match) match.checked = snapshot.checked;
264
+ } else if (el instanceof HTMLInputElement) {
265
+ if (el.type === "checkbox") el.checked = snapshot.checked;
266
+ }
267
+ continue;
268
+ }
269
+ if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
270
+ el.value = snapshot.value;
271
+ }
272
+ }
273
+ }
274
+ var enhance = (root, props) => {
275
+ const { siteId, apiBaseUrl } = props;
276
+ if (!siteId) {
277
+ throw new Error("[sdk:islands] form requires siteId");
278
+ }
279
+ if (!apiBaseUrl) {
280
+ throw new Error("[sdk:islands] form requires apiBaseUrl");
281
+ }
282
+ const apiConfig = {
283
+ baseUrl: apiBaseUrl,
284
+ auth: { type: "none" },
285
+ siteId
286
+ };
287
+ const existingForm = root.querySelector("form");
288
+ const snapshots = snapshotFormValues(existingForm);
289
+ return mountReactIsland(root, ({ root: reactRoot }) => {
290
+ reactRoot.render(
291
+ /* @__PURE__ */ jsx(BlockApiProvider, { config: apiConfig, children: /* @__PURE__ */ jsx(FormNodeClient, { ...props }) })
292
+ );
293
+ requestAnimationFrame(() => {
294
+ const nextForm = root.querySelector("form");
295
+ applySnapshots(nextForm, snapshots);
296
+ });
297
+ });
298
+ };
299
+
300
+ export { decode, enhance };