treege 3.0.0-beta.83 → 3.0.0-beta.84

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 CHANGED
@@ -52,6 +52,7 @@ Treege is a modern React library for creating and rendering interactive decision
52
52
  - **Optional Dependencies**: Graceful degradation when optional packages like `react-native-document-picker` aren't installed
53
53
  - **Theme Support**: Dark/light mode out of the box
54
54
  - **Google API Integration**: Address autocomplete support
55
+ - **Read-Only Viewer**: `TreegeViewer` renders a submitted flow as a label/value recap — same branch-visibility and formatting as the form, with a headless `getViewerFields` core for custom layouts
55
56
 
56
57
  ### Developer Experience
57
58
  - **Modular**: Import only what you need (editor, renderer, or both)
@@ -189,6 +190,73 @@ function App() {
189
190
  }
190
191
  ```
191
192
 
193
+ ## Read-Only Viewer (`TreegeViewer`)
194
+
195
+ Once a form has been submitted, `TreegeViewer` renders the result as a read-only **label / value recap** — no inputs, no validation. It takes the same `flow` and the submitted `values` (the `onSubmit` payload) and replays them through the renderer's branch-visibility logic, so only the fields that were actually reachable for those values are shown. Option values resolve to their labels, dates/ranges and i18n labels are formatted exactly like the form, and `hidden`/`submit` fields are excluded.
196
+
197
+ ```tsx
198
+ import { TreegeRenderer } from "treege/renderer";
199
+ import { TreegeViewer } from "treege/renderer";
200
+ import { useState } from "react";
201
+ import type { Flow, FormValues } from "treege";
202
+
203
+ function App({ flow }: { flow: Flow }) {
204
+ const [submitted, setSubmitted] = useState<FormValues | null>(null);
205
+
206
+ if (submitted) {
207
+ return <TreegeViewer flow={flow} values={submitted} language="en" />;
208
+ }
209
+
210
+ return <TreegeRenderer flow={flow} onSubmit={setSubmitted} />;
211
+ }
212
+ ```
213
+
214
+ ### Props
215
+
216
+ | Prop | Type | Default | Description |
217
+ |----------------------|-----------------------------------------------------|---------|--------------------------------------------------------------------------------------------------------------|
218
+ | `flow` | `Flow` | - | The flow the values were submitted against |
219
+ | `values` | `FormValues` | - | The submitted values (`name`- or `id`-keyed, e.g. the `onSubmit` payload) |
220
+ | `language` | `string` | `"en"` | Language used to resolve translatable labels/options |
221
+ | `baseUrl` | `string` | - | Resolves relative file paths into absolute URLs (same role as on `TreegeRenderer`); `data:`/`blob:`/absolute URLs are left untouched |
222
+ | `excludedFields` | `string[]` | - | Field names (or ids) to hide from the view |
223
+ | `excludeEmptyFields` | `boolean` | `false` | Hide fields that have no submitted value (instead of showing `emptyText`) |
224
+ | `emptyText` | `string` | `"—"` | Text shown when a field has no submitted value |
225
+ | `className` | `string` | - | Extra class names on the root element |
226
+ | `renderField` | `Partial<Record<InputType, (field) => ReactNode>>` | - | Per-type rendering overrides for the value cell (typically `file`) |
227
+ | `renderRow` | `(field, defaultRow) => ReactNode` | - | Wrap or replace a whole field row (label + value) |
228
+
229
+ ### Customizing rendering
230
+
231
+ Use `renderField` to override the value cell for a specific input type — most often `file`, to render thumbnails from your own storage — while every other type keeps its built-in rendering. Use `renderRow` to control the whole row layout (label + value):
232
+
233
+ ```tsx
234
+ <TreegeViewer
235
+ flow={flow}
236
+ values={submitted}
237
+ language="fr"
238
+ excludedFields={["internalNote"]}
239
+ renderField={{ file: ({ rawValue }) => <Thumbnails files={rawValue} /> }}
240
+ />
241
+ ```
242
+
243
+ ### Headless usage (`getViewerFields`)
244
+
245
+ `TreegeViewer` is a thin layer over `getViewerFields`, which returns the ordered, visible, display-ready fields. Use it directly when you want a fully custom layout (a table, a PDF, columns…):
246
+
247
+ ```tsx
248
+ import { getViewerFields } from "treege/renderer";
249
+
250
+ const fields = getViewerFields(flow, values, { language: "en", baseUrl });
251
+
252
+ fields.forEach((field) => {
253
+ // field.label, field.type, field.rawValue
254
+ // field.display — normalized, render-ready value:
255
+ // { kind: "text", text } | { kind: "boolean", checked }
256
+ // { kind: "tags", tags } | { kind: "files", files } | { kind: "empty" }
257
+ });
258
+ ```
259
+
192
260
  ## Module Structure
193
261
 
194
262
  Treege provides multiple import paths for optimal bundle size:
@@ -3739,7 +3739,7 @@ var ca = ({ aiConfig: e, onGenerate: t }) => {
3739
3739
  /* @__PURE__ */ K(fr, {}),
3740
3740
  /* @__PURE__ */ q(dr, {
3741
3741
  className: "tg:font-normal tg:text-muted-foreground tg:text-xs",
3742
- children: ["v", "3.0.0-beta.83"]
3742
+ children: ["v", "3.0.0-beta.84"]
3743
3743
  })
3744
3744
  ]
3745
3745
  })]
package/dist/editor.js CHANGED
@@ -1,3 +1,3 @@
1
- import { t as e } from "./editor-CbcW0OVV.js";
1
+ import { t as e } from "./editor-Fufe7OeU.js";
2
2
  import { n as t, t as n } from "./ThemeContext-BnPOFQC7.js";
3
3
  export { n as ThemeProvider, e as TreegeEditor, t as useTheme };
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
- import { t as e } from "./editor-CbcW0OVV.js";
1
+ import { t as e } from "./editor-Fufe7OeU.js";
2
2
  import { G as t, I as n, J as r, K as i, L as a, U as o, W as s, Y as c, _ as l, a as u, b as d, c as f, g as p, h as m, i as h, l as g, m as _, n as v, o as y, q as b, r as x, s as S, t as C, v as w, y as T } from "./ThemeContext-BnPOFQC7.js";
3
3
  import { C as E, L as D, S as O, _ as k, a as A, b as j, c as M, d as N, g as P, h as F, i as I, m as L, n as R, o as z, r as B, u as V, v as H, x as U, y as W } from "./DefaultSubmitButton-DpeL3OxC.js";
4
4
  import { a as G, c as K, i as q, l as J, n as Y, o as X, r as Z, s as Q } from "./useRenderNode-DQ5lvXuj.js";
5
- import { a as $, i as ee, n as te, o as ne, r as re, s as ie, t as ae } from "./renderer-KRzuU6OD.js";
5
+ import { a as $, i as ee, n as te, o as ne, r as re, s as ie, t as ae } from "./renderer-BwjPBBfm.js";
6
6
  export { E as DefaultAddressInput, O as DefaultAutocompleteInput, U as DefaultCheckboxInput, j as DefaultDateInput, W as DefaultDateRangeInput, H as DefaultFileInput, k as DefaultHiddenInput, P as DefaultHttpInput, D as DefaultInputLabel, F as DefaultNumberInput, L as DefaultPasswordInput, N as DefaultRadioInput, V as DefaultSelectInput, M as DefaultSwitchInput, z as DefaultTextAreaInput, A as DefaultTextInput, I as DefaultTimeInput, B as DefaultTimeRangeInput, $ as Divider, C as ThemeProvider, ne as Title, e as TreegeEditor, ee as TreegeRenderer, K as TreegeRendererProvider, ae as TreegeViewer, x as applyReferenceTransformation, h as buildInitialFormValues, u as calculateReferenceFieldUpdates, y as checkFormFieldHasValue, S as convertFormValuesToNamedFormat, R as defaultInputRenderers, ie as defaultUI, X as evaluateCondition, Q as evaluateConditions, _ as fileNameFromUrl, m as fileToSerializable, p as filesToSerializable, Z as findStartNode, l as formatFileSize, q as getFlowRenderState, o as getStaticTranslations, s as getTranslatableValue, t as getTranslatedText, te as getViewerFields, f as isFieldEmpty, b as isGroupNode, re as isImageFile, r as isInputNode, w as isRemoteFileData, G as isStartNode, c as isUINode, T as normalizeSerializableFiles, g as resolveNodeDefaultValue, n as sanitize, a as sanitizeHttpResponse, d as serializableToFile, i as setTranslatableValue, v as useTheme, Y as useTreegeRenderer, J as useTreegeRendererConfig };
@@ -27,6 +27,11 @@ export interface TreegeViewerProps {
27
27
  * Field names (or ids) to hide from the view.
28
28
  */
29
29
  excludedFields?: string[];
30
+ /**
31
+ * Hide fields that have no submitted value (instead of showing `emptyText`).
32
+ * Useful to render a compact recap of only the filled-in fields.
33
+ */
34
+ excludeEmptyFields?: boolean;
30
35
  /**
31
36
  * Text shown when a field has no submitted value (defaults to `"—"`).
32
37
  */
@@ -66,5 +71,5 @@ export interface TreegeViewerProps {
66
71
  * renderField={{ file: ({ rawValue }) => <Thumbnails files={rawValue} /> }}
67
72
  * />
68
73
  */
69
- declare const TreegeViewer: ({ flow, values, baseUrl, excludedFields, className, renderField, renderRow, emptyText, language, }: TreegeViewerProps) => import("react/jsx-runtime").JSX.Element;
74
+ declare const TreegeViewer: ({ flow, values, baseUrl, excludedFields, excludeEmptyFields, className, renderField, renderRow, emptyText, language, }: TreegeViewerProps) => import("react/jsx-runtime").JSX.Element;
70
75
  export default TreegeViewer;
@@ -377,22 +377,26 @@ var ce = () => /* @__PURE__ */ k("section", {
377
377
  children: n.text
378
378
  });
379
379
  }
380
- }, Z = ({ flow: e, values: t, baseUrl: n, excludedFields: r, className: i, renderField: a, renderRow: o, emptyText: s = "—", language: c = "en" }) => {
381
- let l = E(() => J(e, t, {
380
+ }, Z = ({ flow: e, values: t, baseUrl: n, excludedFields: r, excludeEmptyFields: i, className: a, renderField: o, renderRow: s, emptyText: c = "—", language: l = "en" }) => {
381
+ let u = E(() => J(e, t, {
382
382
  baseUrl: n,
383
- language: c
383
+ language: l
384
384
  }), [
385
385
  e,
386
386
  t,
387
- c,
387
+ l,
388
388
  n
389
- ]), u = E(() => l.filter((e) => !(r?.includes(e.name) || r?.includes(e.id))), [l, r]);
389
+ ]), d = E(() => u.filter((e) => !(r?.includes(e.name) || r?.includes(e.id) || i && e.display.kind === "empty")), [
390
+ u,
391
+ r,
392
+ i
393
+ ]);
390
394
  return /* @__PURE__ */ O("dl", {
391
- className: v("tg:flex tg:flex-col tg:gap-4", i),
392
- children: u.map((e) => {
393
- let t = a?.[e.type], n = t ? t(e) : /* @__PURE__ */ O(X, {
395
+ className: v("tg:flex tg:flex-col tg:gap-4", a),
396
+ children: d.map((e) => {
397
+ let t = o?.[e.type], n = t ? t(e) : /* @__PURE__ */ O(X, {
394
398
  field: e,
395
- emptyText: s
399
+ emptyText: c
396
400
  }), r = /* @__PURE__ */ k("div", {
397
401
  className: "tg:flex tg:flex-col tg:gap-1",
398
402
  children: [/* @__PURE__ */ O("dt", {
@@ -403,7 +407,7 @@ var ce = () => /* @__PURE__ */ k("section", {
403
407
  children: n
404
408
  })]
405
409
  });
406
- return /* @__PURE__ */ O("div", { children: o ? o(e, r) : r }, e.id);
410
+ return /* @__PURE__ */ O("div", { children: s ? s(e, r) : r }, e.id);
407
411
  })
408
412
  });
409
413
  };
package/dist/renderer.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { G as e, I as t, L as n, _ as r, a as i, b as a, c as o, g as s, h as c, i as l, l as u, m as d, n as f, o as p, r as m, s as h, t as g, v as _, y as v } from "./ThemeContext-BnPOFQC7.js";
2
2
  import { C as y, L as b, S as x, _ as S, a as C, b as w, c as T, d as E, g as D, h as O, i as k, m as A, n as j, o as M, r as N, u as P, v as F, x as I, y as L } from "./DefaultSubmitButton-DpeL3OxC.js";
3
3
  import { a as R, c as z, i as B, l as V, n as H, o as U, r as W, s as G } from "./useRenderNode-DQ5lvXuj.js";
4
- import { a as K, i as q, n as J, o as Y, r as X, s as Z, t as Q } from "./renderer-KRzuU6OD.js";
4
+ import { a as K, i as q, n as J, o as Y, r as X, s as Z, t as Q } from "./renderer-BwjPBBfm.js";
5
5
  export { y as DefaultAddressInput, x as DefaultAutocompleteInput, I as DefaultCheckboxInput, w as DefaultDateInput, L as DefaultDateRangeInput, F as DefaultFileInput, S as DefaultHiddenInput, D as DefaultHttpInput, b as DefaultInputLabel, O as DefaultNumberInput, A as DefaultPasswordInput, E as DefaultRadioInput, P as DefaultSelectInput, T as DefaultSwitchInput, M as DefaultTextAreaInput, C as DefaultTextInput, k as DefaultTimeInput, N as DefaultTimeRangeInput, K as Divider, g as ThemeProvider, Y as Title, q as TreegeRenderer, z as TreegeRendererProvider, Q as TreegeViewer, m as applyReferenceTransformation, l as buildInitialFormValues, i as calculateReferenceFieldUpdates, p as checkFormFieldHasValue, h as convertFormValuesToNamedFormat, j as defaultInputRenderers, Z as defaultUI, U as evaluateCondition, G as evaluateConditions, d as fileNameFromUrl, c as fileToSerializable, s as filesToSerializable, W as findStartNode, r as formatFileSize, B as getFlowRenderState, e as getTranslatedText, J as getViewerFields, o as isFieldEmpty, X as isImageFile, _ as isRemoteFileData, R as isStartNode, v as normalizeSerializableFiles, u as resolveNodeDefaultValue, t as sanitize, n as sanitizeHttpResponse, a as serializableToFile, f as useTheme, H as useTreegeRenderer, V as useTreegeRendererConfig };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "treege",
3
3
  "description": "Powerful form generator",
4
4
  "license": "ISC",
5
- "version": "3.0.0-beta.83",
5
+ "version": "3.0.0-beta.84",
6
6
  "type": "module",
7
7
  "types": "./dist/main.d.ts",
8
8
  "module": "./dist/main.js",