@builder.io/sdk-react-native 1.0.33 → 1.0.34

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 (262) hide show
  1. package/lib/browser/commonjs/blocks/text/text.js +1 -1
  2. package/lib/browser/commonjs/constants/sdk-version.js +1 -1
  3. package/lib/browser/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
  4. package/lib/browser/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  5. package/lib/browser/commonjs/helpers/cookie.js +12 -2
  6. package/lib/browser/commonjs/helpers/cookie.js.map +1 -1
  7. package/lib/browser/module/blocks/text/text.js +1 -1
  8. package/lib/browser/module/blocks/text/text.js.map +1 -1
  9. package/lib/browser/module/constants/sdk-version.js +1 -1
  10. package/lib/browser/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
  11. package/lib/browser/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  12. package/lib/browser/module/helpers/cookie.js +11 -2
  13. package/lib/browser/module/helpers/cookie.js.map +1 -1
  14. package/lib/browser/typescript/constants/sdk-version.d.ts +1 -1
  15. package/lib/browser/typescript/helpers/cookie.d.ts +1 -0
  16. package/lib/browser/typescript/helpers/cookie.d.ts.map +1 -1
  17. package/lib/edge/commonjs/blocks/text/text.js +1 -1
  18. package/lib/edge/commonjs/constants/sdk-version.js +1 -1
  19. package/lib/edge/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
  20. package/lib/edge/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  21. package/lib/edge/commonjs/helpers/cookie.js +12 -2
  22. package/lib/edge/commonjs/helpers/cookie.js.map +1 -1
  23. package/lib/edge/module/blocks/text/text.js +1 -1
  24. package/lib/edge/module/blocks/text/text.js.map +1 -1
  25. package/lib/edge/module/constants/sdk-version.js +1 -1
  26. package/lib/edge/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
  27. package/lib/edge/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  28. package/lib/edge/module/helpers/cookie.js +11 -2
  29. package/lib/edge/module/helpers/cookie.js.map +1 -1
  30. package/lib/edge/typescript/constants/sdk-version.d.ts +1 -1
  31. package/lib/edge/typescript/helpers/cookie.d.ts +1 -0
  32. package/lib/edge/typescript/helpers/cookie.d.ts.map +1 -1
  33. package/lib/node/commonjs/blocks/text/text.js +1 -1
  34. package/lib/node/commonjs/constants/sdk-version.js +1 -1
  35. package/lib/node/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
  36. package/lib/node/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  37. package/lib/node/commonjs/helpers/cookie.js +12 -2
  38. package/lib/node/commonjs/helpers/cookie.js.map +1 -1
  39. package/lib/node/module/blocks/text/text.js +1 -1
  40. package/lib/node/module/blocks/text/text.js.map +1 -1
  41. package/lib/node/module/constants/sdk-version.js +1 -1
  42. package/lib/node/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
  43. package/lib/node/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  44. package/lib/node/module/helpers/cookie.js +11 -2
  45. package/lib/node/module/helpers/cookie.js.map +1 -1
  46. package/lib/node/typescript/constants/sdk-version.d.ts +1 -1
  47. package/lib/node/typescript/helpers/cookie.d.ts +1 -0
  48. package/lib/node/typescript/helpers/cookie.d.ts.map +1 -1
  49. package/package.json +10 -7
  50. package/src/blocks/BaseText.tsx +17 -0
  51. package/src/blocks/accordion/accordion.tsx +181 -0
  52. package/src/blocks/accordion/accordion.types.ts +12 -0
  53. package/src/blocks/accordion/component-info.ts +124 -0
  54. package/src/blocks/accordion/helpers.ts +3 -0
  55. package/src/blocks/accordion/index.ts +1 -0
  56. package/src/blocks/button/button.tsx +56 -0
  57. package/src/blocks/button/button.types.ts +7 -0
  58. package/src/blocks/button/component-info.ts +35 -0
  59. package/src/blocks/button/index.ts +1 -0
  60. package/src/blocks/columns/columns.tsx +199 -0
  61. package/src/blocks/columns/columns.types.ts +14 -0
  62. package/src/blocks/columns/component-info.ts +219 -0
  63. package/src/blocks/columns/helpers.ts +3 -0
  64. package/src/blocks/columns/index.ts +1 -0
  65. package/src/blocks/custom-code/component-info.ts +24 -0
  66. package/src/blocks/custom-code/custom-code.tsx +71 -0
  67. package/src/blocks/custom-code/index.ts +1 -0
  68. package/src/blocks/embed/component-info.ts +38 -0
  69. package/src/blocks/embed/embed.tsx +62 -0
  70. package/src/blocks/embed/helpers.ts +2 -0
  71. package/src/blocks/embed/index.ts +1 -0
  72. package/src/blocks/form/form/component-info.ts +233 -0
  73. package/src/blocks/form/form/form.tsx +324 -0
  74. package/src/blocks/form/form/index.ts +1 -0
  75. package/src/blocks/form/input/component-info.ts +47 -0
  76. package/src/blocks/form/input/index.ts +1 -0
  77. package/src/blocks/form/input/input.tsx +49 -0
  78. package/src/blocks/form/select/component-info.ts +44 -0
  79. package/src/blocks/form/select/index.ts +1 -0
  80. package/src/blocks/form/select/select.tsx +54 -0
  81. package/src/blocks/form/submit-button/component-info.ts +27 -0
  82. package/src/blocks/form/submit-button/index.ts +1 -0
  83. package/src/blocks/form/submit-button/submit-button.tsx +34 -0
  84. package/src/blocks/fragment/component-info.ts +8 -0
  85. package/src/blocks/fragment/fragment.tsx +18 -0
  86. package/src/blocks/fragment/fragment.types.ts +5 -0
  87. package/src/blocks/fragment/index.ts +1 -0
  88. package/src/blocks/helpers.ts +43 -0
  89. package/src/blocks/image/component-info.ts +129 -0
  90. package/src/blocks/image/image.helpers.ts +47 -0
  91. package/src/blocks/image/image.tsx +65 -0
  92. package/src/blocks/image/image.types.ts +20 -0
  93. package/src/blocks/image/index.ts +1 -0
  94. package/src/blocks/img/component-info.ts +16 -0
  95. package/src/blocks/img/img.tsx +55 -0
  96. package/src/blocks/img/index.ts +1 -0
  97. package/src/blocks/raw-text/component-info.ts +11 -0
  98. package/src/blocks/raw-text/index.ts +1 -0
  99. package/src/blocks/raw-text/raw-text.tsx +1 -0
  100. package/src/blocks/section/component-info.ts +41 -0
  101. package/src/blocks/section/index.ts +1 -0
  102. package/src/blocks/section/section.tsx +39 -0
  103. package/src/blocks/section/section.types.ts +6 -0
  104. package/src/blocks/slot/component-info.ts +15 -0
  105. package/src/blocks/slot/index.ts +1 -0
  106. package/src/blocks/slot/slot.tsx +42 -0
  107. package/src/blocks/symbol/component-info.ts +35 -0
  108. package/src/blocks/symbol/index.ts +1 -0
  109. package/src/blocks/symbol/symbol.helpers.ts +47 -0
  110. package/src/blocks/symbol/symbol.tsx +100 -0
  111. package/src/blocks/symbol/symbol.types.ts +17 -0
  112. package/src/blocks/tabs/component-info.ts +139 -0
  113. package/src/blocks/tabs/index.ts +1 -0
  114. package/src/blocks/tabs/tabs.tsx +79 -0
  115. package/src/blocks/tabs/tabs.types.ts +13 -0
  116. package/src/blocks/text/component-info.ts +20 -0
  117. package/src/blocks/text/index.ts +1 -0
  118. package/src/blocks/text/text.tsx +105 -0
  119. package/src/blocks/text/text.types.ts +4 -0
  120. package/src/blocks/textarea/component-info.ts +38 -0
  121. package/src/blocks/textarea/index.ts +1 -0
  122. package/src/blocks/textarea/textarea.tsx +41 -0
  123. package/src/blocks/video/component-info.ts +83 -0
  124. package/src/blocks/video/index.ts +1 -0
  125. package/src/blocks/video/video.tsx +70 -0
  126. package/src/blocks/video/video.types.ts +21 -0
  127. package/src/components/block/animator.ts +220 -0
  128. package/src/components/block/block.helpers.ts +124 -0
  129. package/src/components/block/block.tsx +232 -0
  130. package/src/components/block/components/block-styles.tsx +136 -0
  131. package/src/components/block/components/block-wrapper.tsx +52 -0
  132. package/src/components/block/components/component-ref/component-ref.helpers.ts +55 -0
  133. package/src/components/block/components/component-ref/component-ref.tsx +66 -0
  134. package/src/components/block/components/interactive-element.tsx +53 -0
  135. package/src/components/block/components/repeated-block.tsx +37 -0
  136. package/src/components/block/types.ts +6 -0
  137. package/src/components/blocks/blocks-wrapper.tsx +93 -0
  138. package/src/components/blocks/blocks.tsx +57 -0
  139. package/src/components/blocks/blocks.types.ts +7 -0
  140. package/src/components/blocks/index.ts +1 -0
  141. package/src/components/content/components/enable-editor.tsx +472 -0
  142. package/src/components/content/components/styles.helpers.ts +101 -0
  143. package/src/components/content/components/styles.tsx +42 -0
  144. package/src/components/content/content.helpers.ts +40 -0
  145. package/src/components/content/content.tsx +150 -0
  146. package/src/components/content/content.types.ts +13 -0
  147. package/src/components/content/contentProps.types.ts +17 -0
  148. package/src/components/content/index.ts +1 -0
  149. package/src/components/content/wrap-component-ref.ts +6 -0
  150. package/src/components/content-variants/content-variants.tsx +146 -0
  151. package/src/components/content-variants/content-variants.types.ts +84 -0
  152. package/src/components/content-variants/helpers.ts +72 -0
  153. package/src/components/content-variants/index.ts +1 -0
  154. package/src/components/content-variants/inlined-fns.ts +22 -0
  155. package/src/components/dynamic-div.tsx +30 -0
  156. package/src/components/dynamic-renderer/dynamic-renderer.helpers.ts +7 -0
  157. package/src/components/dynamic-renderer/dynamic-renderer.tsx +47 -0
  158. package/src/components/error-boundary.tsx +38 -0
  159. package/src/components/inlined-script.tsx +10 -0
  160. package/src/components/inlined-styles.tsx +10 -0
  161. package/src/constants/builder-registered-components.ts +59 -0
  162. package/src/constants/device-sizes.ts +59 -0
  163. package/src/constants/extra-components.ts +1 -0
  164. package/src/constants/sdk-version.ts +1 -0
  165. package/src/constants/target.ts +3 -0
  166. package/src/context/builder.context.ts +15 -0
  167. package/src/context/components.context.ts +3 -0
  168. package/src/context/index.ts +1 -0
  169. package/src/context/types.ts +38 -0
  170. package/src/functions/apply-patch-with-mutation.ts +61 -0
  171. package/src/functions/camel-to-kebab-case.ts +1 -0
  172. package/src/functions/deopt.ts +6 -0
  173. package/src/functions/evaluate/browser-runtime/browser.ts +61 -0
  174. package/src/functions/evaluate/browser-runtime/index.ts +1 -0
  175. package/src/functions/evaluate/choose-eval.ts +23 -0
  176. package/src/functions/evaluate/edge-runtime/acorn-interpreter.ts +2891 -0
  177. package/src/functions/evaluate/edge-runtime/edge-runtime.ts +89 -0
  178. package/src/functions/evaluate/edge-runtime/index.ts +1 -0
  179. package/src/functions/evaluate/evaluate.ts +76 -0
  180. package/src/functions/evaluate/helpers.ts +56 -0
  181. package/src/functions/evaluate/index.ts +1 -0
  182. package/src/functions/evaluate/node-runtime/index.ts +1 -0
  183. package/src/functions/evaluate/node-runtime/init.ts +33 -0
  184. package/src/functions/evaluate/node-runtime/node-runtime.ts +176 -0
  185. package/src/functions/evaluate/node-runtime/safeDynamicRequire.ts +14 -0
  186. package/src/functions/evaluate/placeholder-runtime.ts +4 -0
  187. package/src/functions/evaluate/should-force-browser-runtime-in-node.ts +16 -0
  188. package/src/functions/event-handler-name.ts +4 -0
  189. package/src/functions/extract-text-styles.ts +24 -0
  190. package/src/functions/fast-clone.ts +4 -0
  191. package/src/functions/fetch-builder-props.ts +75 -0
  192. package/src/functions/get-block-actions-handler.ts +17 -0
  193. package/src/functions/get-block-actions.ts +35 -0
  194. package/src/functions/get-block-component-options.ts +7 -0
  195. package/src/functions/get-block-properties.ts +62 -0
  196. package/src/functions/get-builder-search-params/index.ts +33 -0
  197. package/src/functions/get-class-prop-name.ts +15 -0
  198. package/src/functions/get-content/generate-content-url.ts +88 -0
  199. package/src/functions/get-content/index.ts +99 -0
  200. package/src/functions/get-content/types.ts +157 -0
  201. package/src/functions/get-env.ts +5 -0
  202. package/src/functions/get-fetch.ts +11 -0
  203. package/src/functions/get-global-this.ts +16 -0
  204. package/src/functions/get-processed-block.ts +70 -0
  205. package/src/functions/get-style.ts +38 -0
  206. package/src/functions/get.ts +4 -0
  207. package/src/functions/is-browser.ts +3 -0
  208. package/src/functions/is-edge-runtime.ts +9 -0
  209. package/src/functions/is-editing.ts +8 -0
  210. package/src/functions/is-from-trusted-host.ts +11 -0
  211. package/src/functions/is-iframe.ts +4 -0
  212. package/src/functions/is-node-runtime.ts +8 -0
  213. package/src/functions/is-previewing.ts +16 -0
  214. package/src/functions/on-change.ts +29 -0
  215. package/src/functions/register-component.ts +30 -0
  216. package/src/functions/register.ts +44 -0
  217. package/src/functions/set-editor-settings.ts +15 -0
  218. package/src/functions/set.ts +14 -0
  219. package/src/functions/track/helpers.ts +51 -0
  220. package/src/functions/track/index.ts +131 -0
  221. package/src/functions/track/interaction.ts +63 -0
  222. package/src/functions/transform-block-properties.ts +33 -0
  223. package/src/functions/transform-block.ts +30 -0
  224. package/src/functions/transform-style-property.ts +296 -0
  225. package/src/helpers/ab-tests.ts +166 -0
  226. package/src/helpers/canTrack.ts +2 -0
  227. package/src/helpers/cookie.ts +109 -0
  228. package/src/helpers/css.ts +33 -0
  229. package/src/helpers/flatten.ts +41 -0
  230. package/src/helpers/localStorage.ts +36 -0
  231. package/src/helpers/logger.ts +7 -0
  232. package/src/helpers/nullable.ts +2 -0
  233. package/src/helpers/omit.ts +7 -0
  234. package/src/helpers/preview-lru-cache/get.ts +4 -0
  235. package/src/helpers/preview-lru-cache/helpers.ts +1 -0
  236. package/src/helpers/preview-lru-cache/init.ts +7 -0
  237. package/src/helpers/preview-lru-cache/set.ts +12 -0
  238. package/src/helpers/preview-lru-cache/types.ts +1 -0
  239. package/src/helpers/search/search.ts +18 -0
  240. package/src/helpers/sessionId.ts +37 -0
  241. package/src/helpers/subscribe-to-editor.ts +95 -0
  242. package/src/helpers/time.ts +2 -0
  243. package/src/helpers/url.ts +15 -0
  244. package/src/helpers/uuid.ts +17 -0
  245. package/src/helpers/visitorId.ts +37 -0
  246. package/src/index-helpers/blocks-exports.ts +16 -0
  247. package/src/index-helpers/top-of-file.ts +2 -0
  248. package/src/index.ts +15 -0
  249. package/src/scripts/init-editing.ts +119 -0
  250. package/src/server-index.ts +43 -0
  251. package/src/types/api-version.ts +2 -0
  252. package/src/types/builder-block.ts +89 -0
  253. package/src/types/builder-content.ts +47 -0
  254. package/src/types/builder-props.ts +12 -0
  255. package/src/types/can-track.ts +3 -0
  256. package/src/types/components.ts +119 -0
  257. package/src/types/deep-partial.ts +1 -0
  258. package/src/types/element.ts +57 -0
  259. package/src/types/enforced-partials.ts +19 -0
  260. package/src/types/input.ts +123 -0
  261. package/src/types/targets.ts +1 -0
  262. package/src/types/typescript.ts +9 -0
@@ -0,0 +1,233 @@
1
+ import type { ComponentInfo } from '../../../types/components';
2
+ export const componentInfo: ComponentInfo = {
3
+ name: 'Form:Form',
4
+ // editableTags: ['builder-form-error']
5
+ defaults: {
6
+ responsiveStyles: {
7
+ large: {
8
+ marginTop: '15px',
9
+ paddingBottom: '15px'
10
+ }
11
+ }
12
+ },
13
+ image: 'https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2Fef36d2a846134910b64b88e6d18c5ca5',
14
+ inputs: [{
15
+ name: 'sendSubmissionsTo',
16
+ type: 'string',
17
+ // TODO: save to builder data and user can download as csv
18
+ // TODO: easy for mode too or computed add/remove fields form mode
19
+ // so you can edit details and high level mode at same time...
20
+ // Later - more integrations like mailchimp
21
+ // /api/v1/form-submit?to=mailchimp
22
+ enum: [{
23
+ label: 'Send to email',
24
+ value: 'email',
25
+ helperText: 'Send form submissions to the email address of your choosing'
26
+ }, {
27
+ label: 'Custom',
28
+ value: 'custom',
29
+ helperText: 'Handle where the form requests go manually with a little code, e.g. to your own custom backend'
30
+ }],
31
+ defaultValue: 'email'
32
+ }, {
33
+ name: 'sendSubmissionsToEmail',
34
+ type: 'string',
35
+ required: true,
36
+ // TODO: required: () => options.get("sendSubmissionsTo") === "email"
37
+ defaultValue: 'your@email.com',
38
+ showIf: 'options.get("sendSubmissionsTo") === "email"'
39
+ }, {
40
+ name: 'sendWithJs',
41
+ type: 'boolean',
42
+ helperText: 'Set to false to use basic html form action',
43
+ defaultValue: true,
44
+ showIf: 'options.get("sendSubmissionsTo") === "custom"'
45
+ }, {
46
+ name: 'name',
47
+ type: 'string',
48
+ defaultValue: 'My form'
49
+ // advanced: true
50
+ }, {
51
+ name: 'action',
52
+ type: 'string',
53
+ helperText: 'URL to send the form data to',
54
+ showIf: 'options.get("sendSubmissionsTo") === "custom"'
55
+ }, {
56
+ name: 'contentType',
57
+ type: 'string',
58
+ defaultValue: 'application/json',
59
+ advanced: true,
60
+ // TODO: do automatically if file input
61
+ enum: ['application/json', 'multipart/form-data', 'application/x-www-form-urlencoded'],
62
+ showIf: 'options.get("sendSubmissionsTo") === "custom" && options.get("sendWithJs") === true'
63
+ }, {
64
+ name: 'method',
65
+ type: 'string',
66
+ showIf: 'options.get("sendSubmissionsTo") === "custom"',
67
+ defaultValue: 'POST',
68
+ advanced: true
69
+ }, {
70
+ name: 'previewState',
71
+ type: 'string',
72
+ // TODO: persist: false flag
73
+ enum: ['unsubmitted', 'sending', 'success', 'error'],
74
+ defaultValue: 'unsubmitted',
75
+ helperText: 'Choose a state to edit, e.g. choose "success" to show what users see on success and edit the message',
76
+ showIf: 'options.get("sendSubmissionsTo") !== "zapier" && options.get("sendWithJs") === true'
77
+ }, {
78
+ name: 'successUrl',
79
+ type: 'url',
80
+ helperText: 'Optional URL to redirect the user to on form submission success',
81
+ showIf: 'options.get("sendSubmissionsTo") !== "zapier" && options.get("sendWithJs") === true'
82
+ }, {
83
+ name: 'resetFormOnSubmit',
84
+ type: 'boolean',
85
+ showIf: "options.get('sendSubmissionsTo') === 'custom' && options.get('sendWithJs') === true",
86
+ advanced: true
87
+ }, {
88
+ name: 'successMessage',
89
+ type: 'uiBlocks',
90
+ hideFromUI: true,
91
+ defaultValue: [{
92
+ '@type': '@builder.io/sdk:Element',
93
+ responsiveStyles: {
94
+ large: {
95
+ marginTop: '10px'
96
+ }
97
+ },
98
+ component: {
99
+ name: 'Text',
100
+ options: {
101
+ text: '<span>Thanks!</span>'
102
+ }
103
+ }
104
+ }]
105
+ }, {
106
+ name: 'validate',
107
+ type: 'boolean',
108
+ defaultValue: true,
109
+ advanced: true
110
+ }, {
111
+ name: 'errorMessagePath',
112
+ type: 'text',
113
+ advanced: true,
114
+ helperText: 'Path to where to get the error message from in a JSON response to display to the user, e.g. "error.message" for a response like { "error": { "message": "this username is taken" }}'
115
+ }, {
116
+ name: 'errorMessage',
117
+ type: 'uiBlocks',
118
+ hideFromUI: true,
119
+ defaultValue: [{
120
+ '@type': '@builder.io/sdk:Element',
121
+ responsiveStyles: {
122
+ large: {
123
+ marginTop: '10px'
124
+ }
125
+ },
126
+ bindings: {
127
+ 'component.options.text': 'state.formErrorMessage || block.component.options.text'
128
+ },
129
+ component: {
130
+ name: 'Text',
131
+ options: {
132
+ text: '<span>Form submission error :( Please check your answers and try again</span>'
133
+ }
134
+ }
135
+ }]
136
+ }, {
137
+ name: 'sendingMessage',
138
+ type: 'uiBlocks',
139
+ hideFromUI: true,
140
+ defaultValue: [{
141
+ '@type': '@builder.io/sdk:Element',
142
+ responsiveStyles: {
143
+ large: {
144
+ marginTop: '10px'
145
+ }
146
+ },
147
+ component: {
148
+ name: 'Text',
149
+ options: {
150
+ text: '<span>Sending...</span>'
151
+ }
152
+ }
153
+ }]
154
+ }, {
155
+ name: 'customHeaders',
156
+ type: 'map',
157
+ valueType: {
158
+ type: 'string'
159
+ },
160
+ advanced: true,
161
+ showIf: 'options.get("sendSubmissionsTo") === "custom" && options.get("sendWithJs") === true'
162
+ }],
163
+ noWrap: true,
164
+ canHaveChildren: true,
165
+ defaultChildren: [{
166
+ '@type': '@builder.io/sdk:Element',
167
+ responsiveStyles: {
168
+ large: {
169
+ marginTop: '10px'
170
+ }
171
+ },
172
+ component: {
173
+ name: 'Text',
174
+ options: {
175
+ text: '<span>Enter your name</span>'
176
+ }
177
+ }
178
+ }, {
179
+ '@type': '@builder.io/sdk:Element',
180
+ responsiveStyles: {
181
+ large: {
182
+ marginTop: '10px'
183
+ }
184
+ },
185
+ component: {
186
+ name: 'Form:Input',
187
+ options: {
188
+ name: 'name',
189
+ placeholder: 'Jane Doe'
190
+ }
191
+ }
192
+ }, {
193
+ '@type': '@builder.io/sdk:Element',
194
+ responsiveStyles: {
195
+ large: {
196
+ marginTop: '10px'
197
+ }
198
+ },
199
+ component: {
200
+ name: 'Text',
201
+ options: {
202
+ text: '<span>Enter your email</span>'
203
+ }
204
+ }
205
+ }, {
206
+ '@type': '@builder.io/sdk:Element',
207
+ responsiveStyles: {
208
+ large: {
209
+ marginTop: '10px'
210
+ }
211
+ },
212
+ component: {
213
+ name: 'Form:Input',
214
+ options: {
215
+ name: 'email',
216
+ placeholder: 'jane@doe.com'
217
+ }
218
+ }
219
+ }, {
220
+ '@type': '@builder.io/sdk:Element',
221
+ responsiveStyles: {
222
+ large: {
223
+ marginTop: '10px'
224
+ }
225
+ },
226
+ component: {
227
+ name: 'Form:SubmitButton',
228
+ options: {
229
+ text: 'Submit'
230
+ }
231
+ }
232
+ }]
233
+ }
@@ -0,0 +1,324 @@
1
+ import * as React from "react";
2
+ import BaseText from "../../blocks/BaseText";
3
+ import {
4
+ FlatList,
5
+ ScrollView,
6
+ View,
7
+ StyleSheet,
8
+ Image,
9
+ Text,
10
+ Pressable,
11
+ TextInput,
12
+ } from "react-native";
13
+ import { useState, useRef } from "react";
14
+
15
+ /**
16
+ * This import is used by the Svelte SDK. Do not remove.
17
+ */
18
+
19
+ export type FormProps = BuilderDataProps &
20
+ BuilderComponentsProp &
21
+ BuilderLinkComponentProp & {
22
+ attributes?: any;
23
+ name?: string;
24
+ action?: string;
25
+ validate?: boolean;
26
+ method?: string;
27
+ sendSubmissionsTo?: string;
28
+ sendSubmissionsToEmail?: string;
29
+ sendWithJs?: boolean;
30
+ contentType?: string;
31
+ customHeaders?: {
32
+ [key: string]: string;
33
+ };
34
+ successUrl?: string;
35
+ previewState?: FormState;
36
+ successMessage?: BuilderBlock[];
37
+ errorMessage?: BuilderBlock[];
38
+ sendingMessage?: BuilderBlock[];
39
+ resetFormOnSubmit?: boolean;
40
+ errorMessagePath?: string;
41
+ };
42
+ /**
43
+ * This import is used by the Svelte SDK. Do not remove.
44
+ */
45
+
46
+ export type FormState = "unsubmitted" | "sending" | "success" | "error";
47
+ import Block from "../../../components/block/block";
48
+ import Blocks from "../../../components/blocks/blocks";
49
+ import { getEnv } from "../../../functions/get-env";
50
+ import { get } from "../../../functions/get";
51
+ import { isEditing } from "../../../functions/is-editing";
52
+ import { set } from "../../../functions/set";
53
+ import type { BuilderBlock } from "../../../types/builder-block";
54
+ import type {
55
+ BuilderComponentsProp,
56
+ BuilderDataProps,
57
+ BuilderLinkComponentProp,
58
+ } from "../../../types/builder-props";
59
+ import type { Dictionary } from "../../../types/typescript";
60
+ import { filterAttrs } from "../../helpers";
61
+ import { setAttrs } from "../../helpers";
62
+
63
+ function FormComponent(props: FormProps) {
64
+ const formRef = useRef<HTMLFormElement>(null);
65
+ const [formState, setFormState] = useState(() => "unsubmitted");
66
+
67
+ const [responseData, setResponseData] = useState(() => null);
68
+
69
+ const [formErrorMessage, setFormErrorMessage] = useState(() => "");
70
+
71
+ function mergeNewRootState(newData: Dictionary<any>) {
72
+ const combinedState = {
73
+ ...props.builderContext.rootState,
74
+ ...newData,
75
+ };
76
+ if (props.builderContext.rootSetState) {
77
+ props.builderContext.rootSetState?.(combinedState);
78
+ } else {
79
+ props.builderContext.rootState = combinedState;
80
+ }
81
+ }
82
+
83
+ function submissionState() {
84
+ return (isEditing() && props.previewState) || formState;
85
+ }
86
+
87
+ function onSubmit(event: any) {
88
+ const sendWithJsProp =
89
+ props.sendWithJs || props.sendSubmissionsTo === "email";
90
+ if (props.sendSubmissionsTo === "zapier") {
91
+ event.preventDefault();
92
+ } else if (sendWithJsProp) {
93
+ if (!(props.action || props.sendSubmissionsTo === "email")) {
94
+ event.preventDefault();
95
+ return;
96
+ }
97
+ event.preventDefault();
98
+ const el = event.currentTarget || event.target;
99
+ const headers = props.customHeaders || {};
100
+ let body: any;
101
+ const formData = new FormData(el);
102
+
103
+ // TODO: maybe support null
104
+ const formPairs: {
105
+ key: string;
106
+ value: File | boolean | number | string | FileList;
107
+ }[] = Array.from(el.querySelectorAll("input,select,textarea"))
108
+ .filter((el) => !!(el as HTMLInputElement).name)
109
+ .map((el) => {
110
+ let value: any;
111
+ const key = (el as HTMLImageElement).name;
112
+ if (el instanceof HTMLInputElement) {
113
+ if (el.type === "radio") {
114
+ if (el.checked) {
115
+ value = el.name;
116
+ return {
117
+ key,
118
+ value,
119
+ };
120
+ }
121
+ } else if (el.type === "checkbox") {
122
+ value = el.checked;
123
+ } else if (el.type === "number" || el.type === "range") {
124
+ const num = el.valueAsNumber;
125
+ if (!isNaN(num)) {
126
+ value = num;
127
+ }
128
+ } else if (el.type === "file") {
129
+ // TODO: one vs multiple files
130
+ value = el.files;
131
+ } else {
132
+ value = el.value;
133
+ }
134
+ } else {
135
+ value = (el as HTMLInputElement).value;
136
+ }
137
+ return {
138
+ key,
139
+ value,
140
+ };
141
+ });
142
+ let formContentType = props.contentType;
143
+ if (props.sendSubmissionsTo === "email") {
144
+ formContentType = "multipart/form-data";
145
+ }
146
+ Array.from(formPairs).forEach(({ value }) => {
147
+ if (
148
+ value instanceof File ||
149
+ (Array.isArray(value) && value[0] instanceof File) ||
150
+ value instanceof FileList
151
+ ) {
152
+ formContentType = "multipart/form-data";
153
+ }
154
+ });
155
+
156
+ // TODO: send as urlEncoded or multipart by default
157
+ // because of ease of use and reliability in browser API
158
+ // for encoding the form?
159
+ if (formContentType !== "application/json") {
160
+ body = formData;
161
+ } else {
162
+ // Json
163
+ const json = {};
164
+ Array.from(formPairs).forEach(({ value, key }) => {
165
+ set(json, key, value);
166
+ });
167
+ body = JSON.stringify(json);
168
+ }
169
+ if (formContentType && formContentType !== "multipart/form-data") {
170
+ if (
171
+ /* Zapier doesn't allow content-type header to be sent from browsers */ !(
172
+ sendWithJsProp && props.action?.includes("zapier.com")
173
+ )
174
+ ) {
175
+ headers["content-type"] = formContentType;
176
+ }
177
+ }
178
+ const presubmitEvent = new CustomEvent("presubmit", { detail: { body } });
179
+ if (formRef.current) {
180
+ formRef.current.dispatchEvent(presubmitEvent);
181
+ if (presubmitEvent.defaultPrevented) {
182
+ return;
183
+ }
184
+ }
185
+ setFormState("sending");
186
+ const formUrl = `${
187
+ getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"
188
+ }/api/v1/form-submit?apiKey=${props.builderContext.apiKey}&to=${btoa(
189
+ props.sendSubmissionsToEmail || ""
190
+ )}&name=${encodeURIComponent(props.name || "")}`;
191
+ fetch(
192
+ props.sendSubmissionsTo === "email"
193
+ ? formUrl
194
+ : props.action! /* TODO: throw error if no action URL */,
195
+ { body, headers, method: props.method || "post" }
196
+ ).then(
197
+ async (res) => {
198
+ let body;
199
+ const contentType = res.headers.get("content-type");
200
+ if (contentType && contentType.indexOf("application/json") !== -1) {
201
+ body = await res.json();
202
+ } else {
203
+ body = await res.text();
204
+ }
205
+ if (!res.ok && props.errorMessagePath) {
206
+ /* TODO: allow supplying an error formatter function */ let message =
207
+ get(body, props.errorMessagePath);
208
+ if (message) {
209
+ if (typeof message !== "string") {
210
+ /* TODO: ideally convert json to yaml so it woul dbe like error: - email has been taken */ message =
211
+ JSON.stringify(message);
212
+ }
213
+ setFormErrorMessage(message);
214
+ mergeNewRootState({ formErrorMessage: message });
215
+ }
216
+ }
217
+ setResponseData(body);
218
+ setFormState(res.ok ? "success" : "error");
219
+ if (res.ok) {
220
+ const submitSuccessEvent = new CustomEvent("submit:success", {
221
+ detail: { res, body },
222
+ });
223
+ if (formRef.current) {
224
+ formRef.current.dispatchEvent(submitSuccessEvent);
225
+ if (submitSuccessEvent.defaultPrevented) {
226
+ return;
227
+ }
228
+ /* TODO: option to turn this on/off? */ if (
229
+ props.resetFormOnSubmit !== false
230
+ ) {
231
+ formRef.current.reset();
232
+ }
233
+ }
234
+ /* TODO: client side route event first that can be preventDefaulted */ if (
235
+ props.successUrl
236
+ ) {
237
+ if (formRef.current) {
238
+ const event = new CustomEvent("route", {
239
+ detail: { url: props.successUrl },
240
+ });
241
+ formRef.current.dispatchEvent(event);
242
+ if (!event.defaultPrevented) {
243
+ location.href = props.successUrl;
244
+ }
245
+ } else {
246
+ location.href = props.successUrl;
247
+ }
248
+ }
249
+ }
250
+ },
251
+ (err) => {
252
+ const submitErrorEvent = new CustomEvent("submit:error", {
253
+ detail: { error: err },
254
+ });
255
+ if (formRef.current) {
256
+ formRef.current.dispatchEvent(submitErrorEvent);
257
+ if (submitErrorEvent.defaultPrevented) {
258
+ return;
259
+ }
260
+ }
261
+ setResponseData(err);
262
+ setFormState("error");
263
+ }
264
+ );
265
+ }
266
+ }
267
+ return (
268
+ <View
269
+ validate={props.validate}
270
+ ref={formRef}
271
+ action={!props.sendWithJs && props.action}
272
+ method={props.method}
273
+ name={props.name}
274
+ onSubmit={(event) => onSubmit(event)}
275
+ {...{}}
276
+ {...{}}
277
+ {...props.attributes}
278
+ >
279
+ {props.builderBlock && props.builderBlock.children ? (
280
+ <>
281
+ {props.builderBlock?.children?.map((block, idx) => (
282
+ <Block
283
+ key={`form-block-${idx}`}
284
+ block={block}
285
+ context={props.builderContext}
286
+ registeredComponents={props.builderComponents}
287
+ linkComponent={props.builderLinkComponent}
288
+ />
289
+ ))}
290
+ </>
291
+ ) : null}
292
+ {submissionState() === "error" ? (
293
+ <Blocks
294
+ path="errorMessage"
295
+ blocks={props.errorMessage!}
296
+ context={props.builderContext}
297
+ />
298
+ ) : null}
299
+ {submissionState() === "sending" ? (
300
+ <Blocks
301
+ path="sendingMessage"
302
+ blocks={props.sendingMessage!}
303
+ context={props.builderContext}
304
+ />
305
+ ) : null}
306
+ {submissionState() === "error" && responseData ? (
307
+ <View style={styles.view1}>
308
+ <BaseText>{JSON.stringify(responseData, null, 2)}</BaseText>
309
+ </View>
310
+ ) : null}
311
+ {submissionState() === "success" ? (
312
+ <Blocks
313
+ path="successMessage"
314
+ blocks={props.successMessage!}
315
+ context={props.builderContext}
316
+ />
317
+ ) : null}
318
+ </View>
319
+ );
320
+ }
321
+ const styles = StyleSheet.create({
322
+ view1: { padding: 10, color: "red", textAlign: "center" },
323
+ });
324
+ export default FormComponent;
@@ -0,0 +1 @@
1
+ export { default } from './form'
@@ -0,0 +1,47 @@
1
+ import type { ComponentInfo } from '../../../types/components';
2
+ export const componentInfo: ComponentInfo = {
3
+ name: 'Form:Input',
4
+ image: 'https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2Fad6f37889d9e40bbbbc72cdb5875d6ca',
5
+ inputs: [{
6
+ name: 'type',
7
+ type: 'text',
8
+ enum: ['text', 'number', 'email', 'url', 'checkbox', 'radio', 'range', 'date', 'datetime-local', 'search', 'tel', 'time', 'file', 'month', 'week', 'password', 'color', 'hidden'],
9
+ defaultValue: 'text'
10
+ }, {
11
+ name: 'name',
12
+ type: 'string',
13
+ required: true,
14
+ helperText: 'Every input in a form needs a unique name describing what it takes, e.g. "email"'
15
+ }, {
16
+ name: 'placeholder',
17
+ type: 'string',
18
+ defaultValue: 'Hello there',
19
+ helperText: 'Text to display when there is no value'
20
+ },
21
+ // TODO: handle value vs default value automatically like ng-model
22
+ {
23
+ name: 'defaultValue',
24
+ type: 'string'
25
+ }, {
26
+ name: 'value',
27
+ type: 'string',
28
+ advanced: true
29
+ }, {
30
+ name: 'required',
31
+ type: 'boolean',
32
+ helperText: 'Is this input required to be filled out to submit a form',
33
+ defaultValue: false
34
+ }],
35
+ noWrap: true,
36
+ static: true,
37
+ defaultStyles: {
38
+ paddingTop: '10px',
39
+ paddingBottom: '10px',
40
+ paddingLeft: '10px',
41
+ paddingRight: '10px',
42
+ borderRadius: '3px',
43
+ borderWidth: '1px',
44
+ borderStyle: 'solid',
45
+ borderColor: '#ccc'
46
+ }
47
+ }
@@ -0,0 +1 @@
1
+ export { default } from './input'
@@ -0,0 +1,49 @@
1
+ import * as React from "react";
2
+ import {
3
+ FlatList,
4
+ ScrollView,
5
+ View,
6
+ StyleSheet,
7
+ Image,
8
+ Text,
9
+ Pressable,
10
+ TextInput,
11
+ } from "react-native";
12
+
13
+ /**
14
+ * This import is used by the Svelte SDK. Do not remove.
15
+ */
16
+
17
+ export interface FormInputProps {
18
+ type?: string;
19
+ attributes?: any;
20
+ name?: string;
21
+ value?: string;
22
+ placeholder?: string;
23
+ defaultValue?: string;
24
+ required?: boolean;
25
+ }
26
+
27
+ import { isEditing } from "../../../functions/is-editing";
28
+ import { filterAttrs } from "../../helpers";
29
+ import { setAttrs } from "../../helpers";
30
+
31
+ function FormInputComponent(props: FormInputProps) {
32
+ return (
33
+ <TextInput
34
+ {...{}}
35
+ {...props.attributes}
36
+ key={
37
+ isEditing() && props.defaultValue ? props.defaultValue : "default-key"
38
+ }
39
+ placeholder={props.placeholder}
40
+ type={props.type}
41
+ name={props.name}
42
+ value={props.value}
43
+ defaultValue={props.defaultValue}
44
+ required={props.required}
45
+ />
46
+ );
47
+ }
48
+
49
+ export default FormInputComponent;
@@ -0,0 +1,44 @@
1
+ import type { ComponentInfo } from '../../../types/components';
2
+ export const componentInfo: ComponentInfo = {
3
+ name: 'Form:Select',
4
+ image: 'https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2F83acca093fb24aaf94dee136e9a4b045',
5
+ defaultStyles: {
6
+ alignSelf: 'flex-start'
7
+ },
8
+ inputs: [{
9
+ name: 'options',
10
+ type: 'list',
11
+ required: true,
12
+ subFields: [{
13
+ name: 'value',
14
+ type: 'text',
15
+ required: true
16
+ }, {
17
+ name: 'name',
18
+ type: 'text'
19
+ }],
20
+ defaultValue: [{
21
+ value: 'option 1'
22
+ }, {
23
+ value: 'option 2'
24
+ }]
25
+ }, {
26
+ name: 'name',
27
+ type: 'string',
28
+ required: true,
29
+ helperText: 'Every select in a form needs a unique name describing what it gets, e.g. "email"'
30
+ }, {
31
+ name: 'defaultValue',
32
+ type: 'string'
33
+ }, {
34
+ name: 'value',
35
+ type: 'string',
36
+ advanced: true
37
+ }, {
38
+ name: 'required',
39
+ type: 'boolean',
40
+ defaultValue: false
41
+ }],
42
+ static: true,
43
+ noWrap: true
44
+ }