@lowdefy/docs-content 0.0.0-experimental-20260710073520

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 (304) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +20 -0
  3. package/content/actions/callapi.md +66 -0
  4. package/content/actions/callmethod.md +41 -0
  5. package/content/actions/copytoclipboard.md +32 -0
  6. package/content/actions/displaymessage.md +53 -0
  7. package/content/actions/downloadcsv.md +89 -0
  8. package/content/actions/fetch.md +50 -0
  9. package/content/actions/geolocationcurrentposition.md +56 -0
  10. package/content/actions/link.md +104 -0
  11. package/content/actions/login.md +85 -0
  12. package/content/actions/logout.md +56 -0
  13. package/content/actions/pdfmake.md +304 -0
  14. package/content/actions/request.md +67 -0
  15. package/content/actions/reset.md +27 -0
  16. package/content/actions/resetvalidation.md +85 -0
  17. package/content/actions/scrollto.md +85 -0
  18. package/content/actions/setdarkmode.md +62 -0
  19. package/content/actions/setfocus.md +33 -0
  20. package/content/actions/setglobal.md +63 -0
  21. package/content/actions/setlocale.md +69 -0
  22. package/content/actions/setstate.md +70 -0
  23. package/content/actions/throw.md +72 -0
  24. package/content/actions/validate.md +87 -0
  25. package/content/actions/wait.md +24 -0
  26. package/content/agents/agent-endpoint-tools.md +190 -0
  27. package/content/agents/agent-mcp-tools.md +124 -0
  28. package/content/agents/agent-multi-agent.md +136 -0
  29. package/content/agents/agent-properties.md +174 -0
  30. package/content/agents/agent-server-hooks.md +336 -0
  31. package/content/agents/agentchat.md +515 -0
  32. package/content/agents/agentconversations.md +148 -0
  33. package/content/concepts/ai-agent-docs.md +190 -0
  34. package/content/concepts/cli.md +213 -0
  35. package/content/concepts/connections-and-requests.md +7 -0
  36. package/content/concepts/custom-html.md +3 -0
  37. package/content/concepts/custom-styling.md +161 -0
  38. package/content/concepts/events-and-actions.md +271 -0
  39. package/content/concepts/hosting-files.md +18 -0
  40. package/content/concepts/i18n.md +320 -0
  41. package/content/concepts/keyboard-shortcuts.md +218 -0
  42. package/content/concepts/layout-overview.md +478 -0
  43. package/content/concepts/lists.md +144 -0
  44. package/content/concepts/logger.md +43 -0
  45. package/content/concepts/lowdefy-schema.md +365 -0
  46. package/content/concepts/menus.md +144 -0
  47. package/content/concepts/module-authoring.md +564 -0
  48. package/content/concepts/modules.md +338 -0
  49. package/content/concepts/operators.md +45 -0
  50. package/content/concepts/overview.md +19 -0
  51. package/content/concepts/references-and-templates.md +207 -0
  52. package/content/concepts/secrets.md +24 -0
  53. package/content/concepts/selectors.md +143 -0
  54. package/content/connections/amazonredshift.md +176 -0
  55. package/content/connections/anthropic.md +232 -0
  56. package/content/connections/awss3.md +313 -0
  57. package/content/connections/azureblobstorage.md +133 -0
  58. package/content/connections/elasticsearch.md +371 -0
  59. package/content/connections/google.md +228 -0
  60. package/content/connections/googlecloudstorage.md +139 -0
  61. package/content/connections/googlesheet.md +313 -0
  62. package/content/connections/knex.md +206 -0
  63. package/content/connections/mariadb.md +177 -0
  64. package/content/connections/mcp.md +134 -0
  65. package/content/connections/mongodb.md +739 -0
  66. package/content/connections/mssql.md +191 -0
  67. package/content/connections/mysql.md +192 -0
  68. package/content/connections/openai-connection.md +228 -0
  69. package/content/connections/postgresql.md +200 -0
  70. package/content/connections/redis.md +116 -0
  71. package/content/connections/sendgridmail.md +94 -0
  72. package/content/connections/smtp.md +149 -0
  73. package/content/connections/sqlite.md +187 -0
  74. package/content/connections/stripe.md +115 -0
  75. package/content/container-blocks/affix.md +413 -0
  76. package/content/container-blocks/alert.md +937 -0
  77. package/content/container-blocks/badge.md +1222 -0
  78. package/content/container-blocks/box.md +1453 -0
  79. package/content/container-blocks/card.md +1200 -0
  80. package/content/container-blocks/carousel.md +2247 -0
  81. package/content/container-blocks/collapse.md +1335 -0
  82. package/content/container-blocks/configprovider.md +1070 -0
  83. package/content/container-blocks/confirmmodal.md +1159 -0
  84. package/content/container-blocks/content.md +597 -0
  85. package/content/container-blocks/descriptions.md +870 -0
  86. package/content/container-blocks/drawer.md +1379 -0
  87. package/content/container-blocks/dropdownmenu.md +643 -0
  88. package/content/container-blocks/flex.md +1510 -0
  89. package/content/container-blocks/footer.md +380 -0
  90. package/content/container-blocks/googlemaps.md +546 -0
  91. package/content/container-blocks/googlemapsheatmap.md +607 -0
  92. package/content/container-blocks/googlemapsscript.md +61 -0
  93. package/content/container-blocks/header.md +302 -0
  94. package/content/container-blocks/label.md +739 -0
  95. package/content/container-blocks/layout.md +604 -0
  96. package/content/container-blocks/masonry.md +1090 -0
  97. package/content/container-blocks/mobilemenu.md +1244 -0
  98. package/content/container-blocks/modal.md +1180 -0
  99. package/content/container-blocks/pageheadermenu.md +614 -0
  100. package/content/container-blocks/pagesidebarlayout.md +438 -0
  101. package/content/container-blocks/pagesidermenu.md +651 -0
  102. package/content/container-blocks/popover.md +1421 -0
  103. package/content/container-blocks/result.md +972 -0
  104. package/content/container-blocks/sider.md +1064 -0
  105. package/content/container-blocks/span.md +747 -0
  106. package/content/container-blocks/spinner.md +267 -0
  107. package/content/container-blocks/splitter.md +1735 -0
  108. package/content/container-blocks/tabs.md +1718 -0
  109. package/content/container-blocks/tooltip.md +1274 -0
  110. package/content/container-blocks/watermark.md +515 -0
  111. package/content/controls/for.md +103 -0
  112. package/content/controls/if.md +107 -0
  113. package/content/controls/log.md +50 -0
  114. package/content/controls/parallel.md +71 -0
  115. package/content/controls/parallel_for.md +36 -0
  116. package/content/controls/reject.md +56 -0
  117. package/content/controls/return.md +66 -0
  118. package/content/controls/set_state.md +98 -0
  119. package/content/controls/switch.md +90 -0
  120. package/content/controls/throw.md +79 -0
  121. package/content/controls/try.md +88 -0
  122. package/content/deployment/docker.md +149 -0
  123. package/content/deployment/node-server.md +27 -0
  124. package/content/deployment/vercel.md +101 -0
  125. package/content/display-blocks/aggrid.md +1459 -0
  126. package/content/display-blocks/anchor.md +336 -0
  127. package/content/display-blocks/avatar.md +1154 -0
  128. package/content/display-blocks/breadcrumb.md +517 -0
  129. package/content/display-blocks/button.md +758 -0
  130. package/content/display-blocks/calendar.md +156 -0
  131. package/content/display-blocks/dangeroushtml.md +314 -0
  132. package/content/display-blocks/dangerousmarkdown.md +423 -0
  133. package/content/display-blocks/diffgit.md +44 -0
  134. package/content/display-blocks/difflist.md +225 -0
  135. package/content/display-blocks/diffsidebyside.md +56 -0
  136. package/content/display-blocks/difftimeline.md +94 -0
  137. package/content/display-blocks/divider.md +406 -0
  138. package/content/display-blocks/download.md +60 -0
  139. package/content/display-blocks/dropdownbutton.md +661 -0
  140. package/content/display-blocks/echart.md +418 -0
  141. package/content/display-blocks/floatbutton.md +545 -0
  142. package/content/display-blocks/html.md +311 -0
  143. package/content/display-blocks/icon.md +717 -0
  144. package/content/display-blocks/img.md +479 -0
  145. package/content/display-blocks/markdown.md +520 -0
  146. package/content/display-blocks/markdownwithcode.md +730 -0
  147. package/content/display-blocks/menu.md +1123 -0
  148. package/content/display-blocks/message.md +941 -0
  149. package/content/display-blocks/notification.md +1410 -0
  150. package/content/display-blocks/paragraph.md +643 -0
  151. package/content/display-blocks/progress.md +818 -0
  152. package/content/display-blocks/qrcode.md +519 -0
  153. package/content/display-blocks/s3download.md +240 -0
  154. package/content/display-blocks/search.md +360 -0
  155. package/content/display-blocks/skeleton.md +272 -0
  156. package/content/display-blocks/skeletonavatar.md +222 -0
  157. package/content/display-blocks/skeletonbutton.md +245 -0
  158. package/content/display-blocks/skeletoninput.md +223 -0
  159. package/content/display-blocks/skeletonparagraph.md +201 -0
  160. package/content/display-blocks/statistic.md +485 -0
  161. package/content/display-blocks/steps.md +585 -0
  162. package/content/display-blocks/tag.md +620 -0
  163. package/content/display-blocks/title.md +654 -0
  164. package/content/display-blocks/tour.md +2359 -0
  165. package/content/input-blocks/autocomplete.md +786 -0
  166. package/content/input-blocks/buttonselector.md +964 -0
  167. package/content/input-blocks/checkboxselector.md +765 -0
  168. package/content/input-blocks/checkboxswitch.md +497 -0
  169. package/content/input-blocks/colorselector.md +884 -0
  170. package/content/input-blocks/daterangeselector.md +777 -0
  171. package/content/input-blocks/dateselector.md +693 -0
  172. package/content/input-blocks/datetimeselector.md +791 -0
  173. package/content/input-blocks/inputgallery.md +528 -0
  174. package/content/input-blocks/monthselector.md +717 -0
  175. package/content/input-blocks/multipleselector.md +1337 -0
  176. package/content/input-blocks/numberinput.md +855 -0
  177. package/content/input-blocks/pagination.md +679 -0
  178. package/content/input-blocks/paragraphinput.md +1664 -0
  179. package/content/input-blocks/passwordinput.md +480 -0
  180. package/content/input-blocks/phonenumberinput.md +688 -0
  181. package/content/input-blocks/radioselector.md +820 -0
  182. package/content/input-blocks/ratingslider.md +684 -0
  183. package/content/input-blocks/s3uploadbutton.md +384 -0
  184. package/content/input-blocks/s3uploaddragger.md +305 -0
  185. package/content/input-blocks/s3uploadphoto.md +288 -0
  186. package/content/input-blocks/segmentedselector.md +782 -0
  187. package/content/input-blocks/selector.md +1162 -0
  188. package/content/input-blocks/switch.md +552 -0
  189. package/content/input-blocks/textarea.md +714 -0
  190. package/content/input-blocks/textinput.md +639 -0
  191. package/content/input-blocks/tiptapinput.md +226 -0
  192. package/content/input-blocks/tiptapmentioninput.md +471 -0
  193. package/content/input-blocks/titleinput.md +1094 -0
  194. package/content/input-blocks/treeinput.md +144 -0
  195. package/content/input-blocks/treemultipleselector.md +162 -0
  196. package/content/input-blocks/treeselector.md +185 -0
  197. package/content/input-blocks/upload.md +149 -0
  198. package/content/input-blocks/uploaddragger.md +85 -0
  199. package/content/input-blocks/uploadphoto.md +84 -0
  200. package/content/input-blocks/weekselector.md +630 -0
  201. package/content/list-blocks/controlledlist.md +498 -0
  202. package/content/list-blocks/list.md +529 -0
  203. package/content/list-blocks/listselector.md +301 -0
  204. package/content/list-blocks/masonrylist.md +230 -0
  205. package/content/migration/upgrade-guide.md +106 -0
  206. package/content/migration/v4-to-v5.md +589 -0
  207. package/content/migration/v5-to-v6.md +36 -0
  208. package/content/operators/_actions.md +58 -0
  209. package/content/operators/_and.md +76 -0
  210. package/content/operators/_api.md +254 -0
  211. package/content/operators/_app.md +114 -0
  212. package/content/operators/_args.md +65 -0
  213. package/content/operators/_array.md +331 -0
  214. package/content/operators/_base64.md +49 -0
  215. package/content/operators/_boolean.md +33 -0
  216. package/content/operators/_build.md +166 -0
  217. package/content/operators/_change_case.md +357 -0
  218. package/content/operators/_date.md +415 -0
  219. package/content/operators/_dayjs.md +128 -0
  220. package/content/operators/_diff.md +61 -0
  221. package/content/operators/_divide.md +32 -0
  222. package/content/operators/_eq.md +52 -0
  223. package/content/operators/_event.md +86 -0
  224. package/content/operators/_function.md +52 -0
  225. package/content/operators/_get.md +92 -0
  226. package/content/operators/_global.md +86 -0
  227. package/content/operators/_gt.md +50 -0
  228. package/content/operators/_gte.md +50 -0
  229. package/content/operators/_hash.md +112 -0
  230. package/content/operators/_if.md +30 -0
  231. package/content/operators/_if_none.md +47 -0
  232. package/content/operators/_index.md +48 -0
  233. package/content/operators/_input.md +86 -0
  234. package/content/operators/_intl.md +135 -0
  235. package/content/operators/_item.md +166 -0
  236. package/content/operators/_js.md +113 -0
  237. package/content/operators/_json.md +120 -0
  238. package/content/operators/_jsonata.md +152 -0
  239. package/content/operators/_locale.md +65 -0
  240. package/content/operators/_location.md +40 -0
  241. package/content/operators/_log.md +22 -0
  242. package/content/operators/_lt.md +50 -0
  243. package/content/operators/_lte.md +50 -0
  244. package/content/operators/_math.md +407 -0
  245. package/content/operators/_media.md +83 -0
  246. package/content/operators/_menu.md +62 -0
  247. package/content/operators/_module.md +340 -0
  248. package/content/operators/_mql.md +95 -0
  249. package/content/operators/_ne.md +62 -0
  250. package/content/operators/_not.md +33 -0
  251. package/content/operators/_number.md +159 -0
  252. package/content/operators/_nunjucks.md +117 -0
  253. package/content/operators/_object.md +253 -0
  254. package/content/operators/_operator.md +33 -0
  255. package/content/operators/_or.md +67 -0
  256. package/content/operators/_product.md +45 -0
  257. package/content/operators/_random.md +90 -0
  258. package/content/operators/_ref.md +80 -0
  259. package/content/operators/_regex.md +69 -0
  260. package/content/operators/_request.md +35 -0
  261. package/content/operators/_request_details.md +29 -0
  262. package/content/operators/_secret.md +56 -0
  263. package/content/operators/_state.md +134 -0
  264. package/content/operators/_step.md +98 -0
  265. package/content/operators/_string.md +327 -0
  266. package/content/operators/_subtract.md +24 -0
  267. package/content/operators/_sum.md +45 -0
  268. package/content/operators/_switch.md +37 -0
  269. package/content/operators/_t.md +96 -0
  270. package/content/operators/_theme.md +65 -0
  271. package/content/operators/_type.md +78 -0
  272. package/content/operators/_uri.md +49 -0
  273. package/content/operators/_url_query.md +92 -0
  274. package/content/operators/_user.md +154 -0
  275. package/content/operators/_uuid.md +118 -0
  276. package/content/operators/_var.md +88 -0
  277. package/content/operators/_yaml.md +96 -0
  278. package/content/other/introduction.md +39 -0
  279. package/content/other/next-auth-providers.md +3 -0
  280. package/content/other/updatesession.md +26 -0
  281. package/content/plugins/plugins-actions.md +80 -0
  282. package/content/plugins/plugins-connections.md +98 -0
  283. package/content/plugins/plugins-dev.md +138 -0
  284. package/content/plugins/plugins-introduction.md +29 -0
  285. package/content/plugins/plugins-operators.md +71 -0
  286. package/content/testing/e2e-auth.md +108 -0
  287. package/content/testing/e2e-configuration.md +107 -0
  288. package/content/testing/e2e-getting-started.md +96 -0
  289. package/content/testing/e2e-introduction.md +53 -0
  290. package/content/testing/e2e-mocking.md +155 -0
  291. package/content/testing/e2e-writing-tests.md +214 -0
  292. package/content/tutorial/tutorial-actions-operators.md +222 -0
  293. package/content/tutorial/tutorial-add-blocks.md +86 -0
  294. package/content/tutorial/tutorial-create-page.md +57 -0
  295. package/content/tutorial/tutorial-display-data-page.md +181 -0
  296. package/content/tutorial/tutorial-next-steps.md +53 -0
  297. package/content/tutorial/tutorial-requests-sql.md +22 -0
  298. package/content/tutorial/tutorial-start.md +71 -0
  299. package/content/user-authentication/auth-providers.md +15 -0
  300. package/content/user-authentication/login-and-logout.md +122 -0
  301. package/content/user-authentication/users-introduction.md +31 -0
  302. package/index.json +2281 -0
  303. package/package.json +34 -0
  304. package/scripts/extractAgentDocs.js +130 -0
@@ -0,0 +1,730 @@
1
+ # MarkdownWithCode
2
+
3
+ Render Markdown with syntax-highlighted code blocks.
4
+
5
+ Use the `MarkdownWithCode` block to render code with syntax highlighting.
6
+
7
+ Set properties with `properties.content` and use backticks for `inline code`.
8
+
9
+ Install with `npm install lowdefy` or `pnpm add lowdefy`.
10
+
11
+ The config file is called `lowdefy.yaml` and lives in your project root.
12
+
13
+ Run `npx lowdefy@4 dev` to start the dev server on `http://localhost:3000`.
14
+
15
+ ```yaml
16
+ - id: inline_basic
17
+ type: MarkdownWithCode
18
+ properties:
19
+ content: >
20
+ Use the `MarkdownWithCode` block to render code with syntax highlighting.
21
+
22
+
23
+ Set properties with `properties.content` and use backticks for `inline
24
+ code`.
25
+ - id: inline_in_context
26
+ type: MarkdownWithCode
27
+ properties:
28
+ content: >
29
+ Install with `npm install lowdefy` or `pnpm add lowdefy`.
30
+
31
+
32
+ The config file is called `lowdefy.yaml` and lives in your project root.
33
+
34
+
35
+ Run `npx lowdefy@4 dev` to start the dev server on
36
+ `http://localhost:3000`.
37
+ ```
38
+
39
+ ```yaml
40
+ lowdefy: 4.0.0
41
+
42
+ pages:
43
+ - id: home
44
+ type: PageHeaderMenu
45
+ properties:
46
+ title: My Application
47
+ blocks:
48
+ - id: welcome_title
49
+ type: Title
50
+ properties:
51
+ content: Welcome
52
+ level: 2
53
+ - id: user_form
54
+ type: Card
55
+ properties:
56
+ title: User Information
57
+ blocks:
58
+ - id: name_input
59
+ type: TextInput
60
+ properties:
61
+ label:
62
+ title: Full Name
63
+ - id: email_input
64
+ type: TextInput
65
+ properties:
66
+ label:
67
+ title: Email Address
68
+ - id: submit_button
69
+ type: Button
70
+ properties:
71
+ title: Submit
72
+ type: primary
73
+ events:
74
+ onClick:
75
+ - id: validate
76
+ type: Validate
77
+ ```
78
+
79
+ ```yaml
80
+ - id: code_yaml
81
+ type: MarkdownWithCode
82
+ properties:
83
+ content: |
84
+ ```yaml
85
+ lowdefy: 4.0.0
86
+
87
+ pages:
88
+ - id: home
89
+ type: PageHeaderMenu
90
+ properties:
91
+ title: My Application
92
+ blocks:
93
+ - id: welcome_title
94
+ type: Title
95
+ properties:
96
+ content: Welcome
97
+ level: 2
98
+ - id: user_form
99
+ type: Card
100
+ properties:
101
+ title: User Information
102
+ blocks:
103
+ - id: name_input
104
+ type: TextInput
105
+ properties:
106
+ label:
107
+ title: Full Name
108
+ - id: email_input
109
+ type: TextInput
110
+ properties:
111
+ label:
112
+ title: Email Address
113
+ - id: submit_button
114
+ type: Button
115
+ properties:
116
+ title: Submit
117
+ type: primary
118
+ events:
119
+ onClick:
120
+ - id: validate
121
+ type: Validate
122
+ ```
123
+ ```
124
+
125
+ ```javascript
126
+ function buildConnections({ components, context }) {
127
+ const connections = components.connections ?? [];
128
+
129
+ connections.forEach((connection) => {
130
+ if (!connection.id) {
131
+ throw new Error('Connection id is missing.');
132
+ }
133
+ if (!connection.type) {
134
+ throw new Error(`Connection "${connection.id}" does not have a type.`);
135
+ }
136
+ });
137
+
138
+ return components;
139
+ }
140
+
141
+ export default buildConnections;
142
+ ```
143
+
144
+ ```yaml
145
+ - id: code_javascript
146
+ type: MarkdownWithCode
147
+ properties:
148
+ content: >
149
+ ```javascript
150
+
151
+ function buildConnections({ components, context }) {
152
+ const connections = components.connections ?? [];
153
+
154
+ connections.forEach((connection) => {
155
+ if (!connection.id) {
156
+ throw new Error('Connection id is missing.');
157
+ }
158
+ if (!connection.type) {
159
+ throw new Error(`Connection "${connection.id}" does not have a type.`);
160
+ }
161
+ });
162
+
163
+ return components;
164
+ }
165
+
166
+
167
+ export default buildConnections;
168
+
169
+ ```
170
+ ```
171
+
172
+ ```json
173
+ {
174
+ "name": "@lowdefy/blocks-antd",
175
+ "version": "4.0.0",
176
+ "description": "Ant Design blocks for Lowdefy",
177
+ "main": "dist/index.js",
178
+ "types": [
179
+ {
180
+ "typeName": "Button",
181
+ "category": "display"
182
+ },
183
+ {
184
+ "typeName": "TextInput",
185
+ "category": "input"
186
+ },
187
+ {
188
+ "typeName": "Card",
189
+ "category": "container"
190
+ }
191
+ ],
192
+ "dependencies": {
193
+ "antd": "^6.0.0",
194
+ "react": "^19.0.0"
195
+ }
196
+ }
197
+ ```
198
+
199
+ ```yaml
200
+ - id: code_json
201
+ type: MarkdownWithCode
202
+ properties:
203
+ content: |
204
+ ```json
205
+ {
206
+ "name": "@lowdefy/blocks-antd",
207
+ "version": "4.0.0",
208
+ "description": "Ant Design blocks for Lowdefy",
209
+ "main": "dist/index.js",
210
+ "types": [
211
+ {
212
+ "typeName": "Button",
213
+ "category": "display"
214
+ },
215
+ {
216
+ "typeName": "TextInput",
217
+ "category": "input"
218
+ },
219
+ {
220
+ "typeName": "Card",
221
+ "category": "container"
222
+ }
223
+ ],
224
+ "dependencies": {
225
+ "antd": "^6.0.0",
226
+ "react": "^19.0.0"
227
+ }
228
+ }
229
+ ```
230
+ ```
231
+
232
+ ```python
233
+ import json
234
+ from pathlib import Path
235
+
236
+
237
+ class ConfigLoader:
238
+ """Load and validate Lowdefy configuration files."""
239
+
240
+ def __init__(self, config_path: str):
241
+ self.config_path = Path(config_path)
242
+ self.config = {}
243
+
244
+ def load(self) -> dict:
245
+ with open(self.config_path) as f:
246
+ self.config = json.load(f)
247
+ return self.config
248
+
249
+ def validate(self) -> bool:
250
+ required_keys = ["lowdefy", "pages"]
251
+ return all(key in self.config for key in required_keys)
252
+
253
+
254
+ if __name__ == "__main__":
255
+ loader = ConfigLoader("lowdefy.json")
256
+ config = loader.load()
257
+ print(f"Valid: {loader.validate()}")
258
+ ```
259
+
260
+ ```yaml
261
+ - id: code_python
262
+ type: MarkdownWithCode
263
+ properties:
264
+ content: |
265
+ ```python
266
+ import json
267
+ from pathlib import Path
268
+
269
+
270
+ class ConfigLoader:
271
+ """Load and validate Lowdefy configuration files."""
272
+
273
+ def __init__(self, config_path: str):
274
+ self.config_path = Path(config_path)
275
+ self.config = {}
276
+
277
+ def load(self) -> dict:
278
+ with open(self.config_path) as f:
279
+ self.config = json.load(f)
280
+ return self.config
281
+
282
+ def validate(self) -> bool:
283
+ required_keys = ["lowdefy", "pages"]
284
+ return all(key in self.config for key in required_keys)
285
+
286
+
287
+ if __name__ == "__main__":
288
+ loader = ConfigLoader("lowdefy.json")
289
+ config = loader.load()
290
+ print(f"Valid: {loader.validate()}")
291
+ ```
292
+ ```
293
+
294
+ ```typescript
295
+ interface BlockMeta {
296
+ category: 'display' | 'input' | 'container' | 'list';
297
+ icons: string[];
298
+ styles: string[];
299
+ }
300
+
301
+ interface BlockComponent<P = Record<string, unknown>> {
302
+ blockId: string;
303
+ properties: P;
304
+ methods: {
305
+ setState: (state: Record<string, unknown>) => void;
306
+ triggerEvent: (event: { name: string }) => Promise<void>;
307
+ };
308
+ }
309
+
310
+ function createBlock<P>(
311
+ render: (props: BlockComponent<P>) => JSX.Element,
312
+ meta: BlockMeta
313
+ ): typeof render & { meta: BlockMeta } {
314
+ const block = render as typeof render & { meta: BlockMeta };
315
+ block.meta = meta;
316
+ return block;
317
+ }
318
+ ```
319
+
320
+ ```yaml
321
+ - id: code_typescript
322
+ type: MarkdownWithCode
323
+ properties:
324
+ content: |
325
+ ```typescript
326
+ interface BlockMeta {
327
+ category: 'display' | 'input' | 'container' | 'list';
328
+ icons: string[];
329
+ styles: string[];
330
+ }
331
+
332
+ interface BlockComponent<P = Record<string, unknown>> {
333
+ blockId: string;
334
+ properties: P;
335
+ methods: {
336
+ setState: (state: Record<string, unknown>) => void;
337
+ triggerEvent: (event: { name: string }) => Promise<void>;
338
+ };
339
+ }
340
+
341
+ function createBlock<P>(
342
+ render: (props: BlockComponent<P>) => JSX.Element,
343
+ meta: BlockMeta
344
+ ): typeof render & { meta: BlockMeta } {
345
+ const block = render as typeof render & { meta: BlockMeta };
346
+ block.meta = meta;
347
+ return block;
348
+ }
349
+ ```
350
+ ```
351
+
352
+ ```html
353
+ <!DOCTYPE html>
354
+ <html lang="en">
355
+ <head>
356
+ <meta charset="UTF-8" />
357
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
358
+ <title>Lowdefy App</title>
359
+ <link rel="stylesheet" href="/styles.css" />
360
+ </head>
361
+ <body>
362
+ <div id="root">
363
+ <header class="app-header">
364
+ <h1>My Application</h1>
365
+ <nav>
366
+ <a href="/dashboard">Dashboard</a>
367
+ <a href="/settings">Settings</a>
368
+ </nav>
369
+ </header>
370
+ <main class="content"></main>
371
+ </div>
372
+ <script src="/bundle.js"></script>
373
+ </body>
374
+ </html>
375
+ ```
376
+
377
+ ```yaml
378
+ - id: code_html
379
+ type: MarkdownWithCode
380
+ properties:
381
+ content: >
382
+ ```html
383
+
384
+ <!DOCTYPE html>
385
+
386
+ <html lang="en">
387
+ <head>
388
+ <meta charset="UTF-8" />
389
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
390
+ <title>Lowdefy App</title>
391
+ <link rel="stylesheet" href="/styles.css" />
392
+ </head>
393
+ <body>
394
+ <div id="root">
395
+ <header class="app-header">
396
+ <h1>My Application</h1>
397
+ <nav>
398
+ <a href="/dashboard">Dashboard</a>
399
+ <a href="/settings">Settings</a>
400
+ </nav>
401
+ </header>
402
+ <main class="content"></main>
403
+ </div>
404
+ <script src="/bundle.js"></script>
405
+ </body>
406
+ </html>
407
+
408
+ ```
409
+ ```
410
+
411
+ ```nunjucks
412
+ {# Lowdefy docs page template #}
413
+ _ref:
414
+ path: templates/general.yaml.njk
415
+ vars:
416
+ pageId: {{ pageId }}
417
+ pageTitle: {{ pageTitle }}
418
+ section: {{ section }}
419
+ fullWidth: true
420
+ content:
421
+ - id: intro
422
+ type: Markdown
423
+ properties:
424
+ content: |
425
+ {{ description }}
426
+ {% for example in examples %}
427
+ - id: example_{{ loop.index }}
428
+ type: {{ example.block_type }}
429
+ properties:
430
+ {{ example.properties | dump | safe }}
431
+ {% endfor %}
432
+ ```
433
+
434
+ ```yaml
435
+ - id: code_nunjucks
436
+ type: MarkdownWithCode
437
+ properties:
438
+ content: |
439
+ ```nunjucks
440
+ {# Lowdefy docs page template #}
441
+ _ref:
442
+ path: templates/general.yaml.njk
443
+ vars:
444
+ pageId: {{ pageId }}
445
+ pageTitle: {{ pageTitle }}
446
+ section: {{ section }}
447
+ fullWidth: true
448
+ content:
449
+ - id: intro
450
+ type: Markdown
451
+ properties:
452
+ content: |
453
+ {{ description }}
454
+ {% for example in examples %}
455
+ - id: example_{{ loop.index }}
456
+ type: {{ example.block_type }}
457
+ properties:
458
+ {{ example.properties | dump | safe }}
459
+ {% endfor %}
460
+ ```
461
+ ```
462
+
463
+ ## Building a Form with Lowdefy
464
+
465
+ Follow these steps to create a simple contact form.
466
+
467
+ ### 1. Create the Page
468
+
469
+ Start by defining a page in your `lowdefy.yaml`:
470
+
471
+ ```yaml
472
+ pages:
473
+ - id: contact
474
+ type: PageHeaderMenu
475
+ properties:
476
+ title: Contact Us
477
+ ```
478
+
479
+ ### 2. Add Form Fields
480
+
481
+ Add input blocks inside the page:
482
+
483
+ ```yaml
484
+ blocks:
485
+ - id: name
486
+ type: TextInput
487
+ properties:
488
+ label:
489
+ title: Your Name
490
+ - id: message
491
+ type: TextArea
492
+ properties:
493
+ label:
494
+ title: Message
495
+ ```
496
+
497
+ ### 3. Handle Submission
498
+
499
+ Use an action to process the form data:
500
+
501
+ ```javascript
502
+ // The _state operator accesses form values
503
+ // _state.name returns the value of the "name" TextInput
504
+ // _state.message returns the value of the "message" TextArea
505
+ ```
506
+
507
+ > **Tip:** Use the `Validate` action before `Request` to ensure all required fields are filled in.
508
+
509
+ For the complete guide, see the [Lowdefy documentation](https://docs.lowdefy.com).
510
+
511
+ ```yaml
512
+ - id: mixed_tutorial
513
+ type: MarkdownWithCode
514
+ properties:
515
+ content: >
516
+ ## Building a Form with Lowdefy
517
+
518
+
519
+ Follow these steps to create a simple contact form.
520
+
521
+
522
+ ### 1. Create the Page
523
+
524
+
525
+ Start by defining a page in your `lowdefy.yaml`:
526
+
527
+
528
+ ```yaml
529
+
530
+ pages:
531
+ - id: contact
532
+ type: PageHeaderMenu
533
+ properties:
534
+ title: Contact Us
535
+ ```
536
+
537
+
538
+ ### 2. Add Form Fields
539
+
540
+
541
+ Add input blocks inside the page:
542
+
543
+
544
+ ```yaml
545
+ blocks:
546
+ - id: name
547
+ type: TextInput
548
+ properties:
549
+ label:
550
+ title: Your Name
551
+ - id: message
552
+ type: TextArea
553
+ properties:
554
+ label:
555
+ title: Message
556
+ ```
557
+
558
+
559
+ ### 3. Handle Submission
560
+
561
+
562
+ Use an action to process the form data:
563
+
564
+
565
+ ```javascript
566
+
567
+ // The _state operator accesses form values
568
+
569
+ // _state.name returns the value of the "name" TextInput
570
+
571
+ // _state.message returns the value of the "message" TextArea
572
+
573
+ ```
574
+
575
+
576
+ > **Tip:** Use the `Validate` action before `Request` to ensure all
577
+ required fields are filled in.
578
+
579
+
580
+ For the complete guide, see the [Lowdefy
581
+ documentation](https://docs.lowdefy.com).
582
+ ```
583
+
584
+ ### Configuration vs Code
585
+
586
+ The same logic expressed in YAML config and JavaScript:
587
+
588
+ **Lowdefy YAML:**
589
+ ```yaml
590
+ - id: greeting
591
+ type: Paragraph
592
+ properties:
593
+ content:
594
+ _if:
595
+ test:
596
+ _state: logged_in
597
+ then:
598
+ _string.concat:
599
+ - 'Welcome back, '
600
+ - _state: username
601
+ - '!'
602
+ else: Please log in to continue.
603
+ ```
604
+
605
+ **Equivalent JavaScript:**
606
+ ```javascript
607
+ function getGreeting(state) {
608
+ if (state.logged_in) {
609
+ return `Welcome back, ${state.username}!`;
610
+ }
611
+ return 'Please log in to continue.';
612
+ }
613
+ ```
614
+
615
+ ```yaml
616
+ - id: multi_language
617
+ type: MarkdownWithCode
618
+ properties:
619
+ content: |
620
+ ### Configuration vs Code
621
+
622
+ The same logic expressed in YAML config and JavaScript:
623
+
624
+ **Lowdefy YAML:**
625
+ ```yaml
626
+ - id: greeting
627
+ type: Paragraph
628
+ properties:
629
+ content:
630
+ _if:
631
+ test:
632
+ _state: logged_in
633
+ then:
634
+ _string.concat:
635
+ - 'Welcome back, '
636
+ - _state: username
637
+ - '!'
638
+ else: Please log in to continue.
639
+ ```
640
+
641
+ **Equivalent JavaScript:**
642
+ ```javascript
643
+ function getGreeting(state) {
644
+ if (state.logged_in) {
645
+ return `Welcome back, ${state.username}!`;
646
+ }
647
+ return 'Please log in to continue.';
648
+ }
649
+ ```
650
+ ```
651
+
652
+ **skipHtml: false (default)**
653
+
654
+ HTML tags like `<b>` are escaped and shown as text in the output. This is the default, safe behavior.
655
+
656
+ **skipHtml: true**
657
+
658
+ With skipHtml enabled, any HTML tags like <b>bold</b> are completely removed from the output rather than shown as escaped text.
659
+
660
+ ```yaml
661
+ - id: skip_html_false
662
+ type: MarkdownWithCode
663
+ properties:
664
+ content: >
665
+ **skipHtml: false (default)**
666
+
667
+
668
+ HTML tags like `<b>` are escaped and shown as text in the output. This is
669
+ the default, safe behavior.
670
+ - id: skip_html_true
671
+ type: MarkdownWithCode
672
+ properties:
673
+ skipHtml: true
674
+ content: >
675
+ **skipHtml: true**
676
+
677
+
678
+ With skipHtml enabled, any HTML tags like <b>bold</b> are completely
679
+ removed from the output rather than shown as escaped text.
680
+ ```
681
+
682
+ ### Styled Code Container
683
+
684
+ The `element` style key wraps the entire block:
685
+
686
+ ```yaml
687
+ style:
688
+ .element:
689
+ backgroundColor: var(--ant-color-success-bg)
690
+ padding: 16
691
+ borderRadius: 8
692
+ ```
693
+
694
+ ```yaml
695
+ - id: style_element
696
+ type: MarkdownWithCode
697
+ style:
698
+ .element:
699
+ backgroundColor: var(--ant-color-success-bg)
700
+ padding: 16
701
+ borderRadius: 8
702
+ border: 1px solid var(--ant-color-success-border)
703
+ properties:
704
+ content: |
705
+ ### Styled Code Container
706
+
707
+ The `element` style key wraps the entire block:
708
+
709
+ ```yaml
710
+ style:
711
+ .element:
712
+ backgroundColor: var(--ant-color-success-bg)
713
+ padding: 16
714
+ borderRadius: 8
715
+ ```
716
+ ```
717
+
718
+ | Property | Type | Default | Description |
719
+ | --- | --- | --- | --- |
720
+ | `content` | string | - | Content in markdown format. |
721
+ | `skipHtml` | boolean | `false` | By default, HTML in markdown is escaped. When true all HTML code in the markdown will not be rendered. |
722
+
723
+ No events defined.
724
+
725
+ | Key | Target |
726
+ | --- | --- |
727
+ | `/block` | Outer block wrapper (always available). |
728
+ | `/element` | The MarkdownWithCode element. |
729
+
730
+ No slots defined.