@formbox/htmx 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -15
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@ React, hydrate React, or manage MobX.
|
|
|
9
9
|
The main API is built around a short-lived renderer instance:
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
import { QuestionnaireRenderer,
|
|
12
|
+
import { QuestionnaireRenderer, loadDefaultTemplates } from "@formbox/htmx";
|
|
13
13
|
|
|
14
14
|
const route = "/questionnaire";
|
|
15
|
-
const templates = await
|
|
15
|
+
const templates = await loadDefaultTemplates();
|
|
16
16
|
const renderer = new QuestionnaireRenderer({
|
|
17
17
|
token: "encounter-questionnaire",
|
|
18
18
|
templates,
|
|
@@ -55,9 +55,9 @@ field encoding and parses the submitted payload in `renderer.process()`.
|
|
|
55
55
|
## Basic Integration
|
|
56
56
|
|
|
57
57
|
```ts
|
|
58
|
-
import { QuestionnaireRenderer,
|
|
58
|
+
import { QuestionnaireRenderer, loadDefaultTemplates } from "@formbox/htmx";
|
|
59
59
|
|
|
60
|
-
const templates = await
|
|
60
|
+
const templates = await loadDefaultTemplates();
|
|
61
61
|
|
|
62
62
|
async function renderQuestionnaire(request: Request): Promise<Response> {
|
|
63
63
|
const route = "/questionnaire";
|
|
@@ -90,6 +90,72 @@ async function renderQuestionnaire(request: Request): Promise<Response> {
|
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
## HTMX Integration
|
|
94
|
+
|
|
95
|
+
The renderer does not own your page shell. If a POST should update more than
|
|
96
|
+
the form itself, such as a status label or a rendered `QuestionnaireResponse`
|
|
97
|
+
preview beside the form, target an application-owned wrapper and return that
|
|
98
|
+
same wrapper for HTMX requests.
|
|
99
|
+
|
|
100
|
+
For dynamic questionnaires, prefer morphdom swaps so focus and nearby DOM state
|
|
101
|
+
survive server-rendered updates better than plain `outerHTML` replacement:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import {
|
|
105
|
+
compileTemplates,
|
|
106
|
+
loadDefaultTemplates,
|
|
107
|
+
loadTemplates,
|
|
108
|
+
} from "@formbox/htmx";
|
|
109
|
+
|
|
110
|
+
const templates = {
|
|
111
|
+
...(await loadDefaultTemplates()),
|
|
112
|
+
...(await loadTemplates("./questionnaire-templates")),
|
|
113
|
+
...compileTemplates({
|
|
114
|
+
Form: `
|
|
115
|
+
<form{{{attrs attributes}}} hx-target="#questionnaire-app" hx-swap="morphdom">
|
|
116
|
+
{{{fields}}}
|
|
117
|
+
</form>
|
|
118
|
+
`,
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
async function handler(request: Request): Promise<Response> {
|
|
123
|
+
const rendered = await renderQuestionnaire(request);
|
|
124
|
+
const body =
|
|
125
|
+
request.headers.get("hx-request") === "true"
|
|
126
|
+
? questionnaireApp(rendered)
|
|
127
|
+
: layout(questionnaireApp(rendered));
|
|
128
|
+
|
|
129
|
+
return html(body);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function questionnaireApp(rendered: {
|
|
133
|
+
form: string;
|
|
134
|
+
response: unknown;
|
|
135
|
+
}): string {
|
|
136
|
+
return `
|
|
137
|
+
<div id="questionnaire-app">
|
|
138
|
+
${rendered.form}
|
|
139
|
+
<pre>${JSON.stringify(rendered.response, null, 2)}</pre>
|
|
140
|
+
</div>
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Include the HTMX morphdom extension in the application shell:
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<script src="https://unpkg.com/morphdom@2.7.8/dist/morphdom-umd.min.js"></script>
|
|
149
|
+
<script src="https://unpkg.com/htmx-ext-morphdom-swap@2.0.0/morphdom-swap.js"></script>
|
|
150
|
+
<body hx-ext="morphdom-swap">
|
|
151
|
+
<div id="questionnaire-app">...</div>
|
|
152
|
+
</body>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Use the default form swap when the form is the only dynamic region. Use an
|
|
156
|
+
application wrapper when the result of `renderer.process(formData)` affects
|
|
157
|
+
nearby UI outside the form.
|
|
158
|
+
|
|
93
159
|
## Lifecycle
|
|
94
160
|
|
|
95
161
|
Create one renderer instance for one request/render cycle:
|
|
@@ -129,8 +195,8 @@ const renderer = new QuestionnaireRenderer({
|
|
|
129
195
|
|
|
130
196
|
`questionnaireResponse` is optional initial state.
|
|
131
197
|
`token` is required and must be unique for each rendered form on the same page.
|
|
132
|
-
`templates` is required; call `await
|
|
133
|
-
|
|
198
|
+
`templates` is required; call `await loadDefaultTemplates()` for the package
|
|
199
|
+
defaults, or merge those templates with application overrides.
|
|
134
200
|
|
|
135
201
|
### `renderer.process(formData)`
|
|
136
202
|
|
|
@@ -182,10 +248,10 @@ Use a custom `Form` template when the application needs to add shell markup or
|
|
|
182
248
|
adjust attributes:
|
|
183
249
|
|
|
184
250
|
```ts
|
|
185
|
-
import { compileTemplates,
|
|
251
|
+
import { compileTemplates, loadDefaultTemplates } from "@formbox/htmx";
|
|
186
252
|
|
|
187
253
|
const templates = {
|
|
188
|
-
...(await
|
|
254
|
+
...(await loadDefaultTemplates()),
|
|
189
255
|
...compileTemplates({
|
|
190
256
|
Form: `
|
|
191
257
|
<form{{{attrs attributes}}}>
|
|
@@ -245,22 +311,22 @@ const templates = compileTemplates({
|
|
|
245
311
|
});
|
|
246
312
|
```
|
|
247
313
|
|
|
248
|
-
Load the
|
|
314
|
+
Load the default templates explicitly:
|
|
249
315
|
|
|
250
316
|
```ts
|
|
251
|
-
import {
|
|
317
|
+
import { loadDefaultTemplates } from "@formbox/htmx";
|
|
252
318
|
|
|
253
|
-
const templates = await
|
|
319
|
+
const templates = await loadDefaultTemplates();
|
|
254
320
|
```
|
|
255
321
|
|
|
256
322
|
If you prefer overrides as files, load a directory of `*.html.hbs` files and
|
|
257
|
-
merge the result with the
|
|
323
|
+
merge the result with the default templates:
|
|
258
324
|
|
|
259
325
|
```ts
|
|
260
|
-
import {
|
|
326
|
+
import { loadDefaultTemplates, loadTemplates } from "@formbox/htmx";
|
|
261
327
|
|
|
262
328
|
const templates = {
|
|
263
|
-
...(await
|
|
329
|
+
...(await loadDefaultTemplates()),
|
|
264
330
|
...(await loadTemplates("./questionnaire-templates")),
|
|
265
331
|
};
|
|
266
332
|
```
|
|
@@ -285,7 +351,7 @@ Available Handlebars helpers:
|
|
|
285
351
|
Use triple braces for renderer-provided HTML slots such as `fields`, `children`,
|
|
286
352
|
`label`, `errors`, and `customOptionForm`.
|
|
287
353
|
|
|
288
|
-
|
|
354
|
+
Default templates and user templates use the same data shape. The package does
|
|
289
355
|
not keep a separate JSX fallback path.
|
|
290
356
|
|
|
291
357
|
### `renderer.getQuestionnaireResponse()`
|
package/dist/index.d.ts
CHANGED
|
@@ -298,7 +298,7 @@ export declare type LinkTemplateProperties = Omit<TemplateBase<LinkProperties>,
|
|
|
298
298
|
readonly children: string;
|
|
299
299
|
};
|
|
300
300
|
|
|
301
|
-
export declare function
|
|
301
|
+
export declare function loadDefaultTemplates(): Promise<RequiredTemplates>;
|
|
302
302
|
|
|
303
303
|
export declare function loadTemplates(directory: string | URL): Promise<Templates>;
|
|
304
304
|
|
package/dist/index.js
CHANGED
|
@@ -59781,7 +59781,7 @@ function compileTemplates(sources) {
|
|
|
59781
59781
|
})
|
|
59782
59782
|
);
|
|
59783
59783
|
}
|
|
59784
|
-
async function
|
|
59784
|
+
async function loadDefaultTemplates() {
|
|
59785
59785
|
const templates = await loadTemplates(
|
|
59786
59786
|
new URL(
|
|
59787
59787
|
/* @vite-ignore */
|
|
@@ -59791,7 +59791,7 @@ async function loadNativeTemplates() {
|
|
|
59791
59791
|
);
|
|
59792
59792
|
const missing = templateNames.filter((name) => templates[name] === void 0);
|
|
59793
59793
|
if (missing.length > 0) {
|
|
59794
|
-
throw new Error(`Missing
|
|
59794
|
+
throw new Error(`Missing default template files: ${missing.join(", ")}`);
|
|
59795
59795
|
}
|
|
59796
59796
|
return templates;
|
|
59797
59797
|
}
|
|
@@ -62382,6 +62382,6 @@ export {
|
|
|
62382
62382
|
compileTemplate,
|
|
62383
62383
|
compileTemplates,
|
|
62384
62384
|
htmlAttributes,
|
|
62385
|
-
|
|
62385
|
+
loadDefaultTemplates,
|
|
62386
62386
|
loadTemplates
|
|
62387
62387
|
};
|