Skip to content

Commit 89f0f46

Browse files
committed
docs: clarify how to get data using Renderer*Scope in custom rendering
* Update the custom-rendering.md documentation to accurately explain that stringContent, numberContent, and booleanContent slots receive specialized scope objects (RendererStringScope, RendererNumberScope, RendererBooleanScope). * Describe how these scopes provide access to field metadata, options, and validation by connecting the UI schema, JSON schema, and form state. * Add example usage showing how to use the scope API to access label, enabled state, and other metadata for custom field rendering. * Improve clarity for users customizing JsonForm rendering, ensuring they understand how to leverage the scope interfaces for advanced UI scenarios. Closes #16
1 parent d936d6d commit 89f0f46

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

docs/custom-rendering.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
This page explains how to customize the default rendering of a `JsonForm` component in
2+
`jsonforms-kotlin`. You can provide your own UI for specific fields or layouts by supplying custom
3+
composable functions to the `JsonForm` component. This allows you to tailor the form's appearance
4+
and behavior to your application's needs.
5+
6+
## Why Customize Rendering?
7+
8+
While the default renderers (such as Material3 or Cupertino) provide a consistent look and feel,
9+
you may want to:
10+
11+
* Integrate custom UI components (e.g., dropdowns, country pickers)
12+
* Change the layout or style of certain fields
13+
* Add special logic for user interaction
14+
15+
## How to Customize Rendering
16+
17+
You can customize rendering by providing your own implementations for the `layoutContent`,
18+
`stringContent`, `numberContent`, and `booleanContent` slots in the `JsonForm` composable. Each
19+
slot receives the necessary context (such as the field id and current value) and should emit your
20+
custom ui component.
21+
22+
**Example: Custom dropdown for country selection**
23+
24+
Here, the `flags` field uses a custom dropdown, while other fields use the default Material3
25+
renderer:
26+
27+
```kotlin
28+
JsonForm(
29+
schema = schema,
30+
uiSchema = uiSchema,
31+
state = state,
32+
layoutContent = { Material3Layout(content = it) },
33+
stringContent = { id ->
34+
val value = state[id].value as String?
35+
val error = state.error(id = id).value
36+
if (id == "flags") {
37+
FlagDropdownField(
38+
value = value,
39+
values = values(), // your list of country codes described in the schema
40+
expanded = expanded,
41+
onFlagClick = { expanded = !expanded },
42+
onItemClick = { state[id] = it },
43+
onDismissRequest = { expanded = false },
44+
)
45+
} else {
46+
Material3StringProperty(
47+
value = value,
48+
error = error?.message,
49+
onValueChange = { state[id] = it },
50+
)
51+
}
52+
},
53+
numberContent = {},
54+
booleanContent = {},
55+
)
56+
```
57+
58+
* The `stringContent` lambda checks the field id. If it's `flags`, it renders a custom dropdown. Otherwise, it falls back to the default Material3 field.
59+
* You can use this pattern to override rendering for any field or layout.
60+
61+
## Accessing data from schema and UI schema
62+
63+
When customizing rendering, the `stringContent`, `numberContent`, and `booleanContent` slots each
64+
receive a specialized scope object: `RendererStringScope`, `RendererNumberScope`, or
65+
`RendererBooleanScope`.
66+
67+
These scope interfaces provide a rich API to access metadata and configuration for the field being
68+
rendered, by connecting the UI schema (which describes the form layout and controls) with the JSON
69+
schema (which describes the data model and validation rules). The internal implementation of each
70+
scope uses both schemas and the current form state to provide the following:
71+
72+
```kotlin
73+
stringContent = { id ->
74+
val value = state[id].value as String?
75+
val error = state.error(id).value
76+
val label = this.label()
77+
val enabled = this.enabled()
78+
// ...render your custom field using this metadata...
79+
}
80+
```
81+
82+
## Tips for Customization
83+
84+
* You can mix and match custom and default renderers as needed.
85+
* Use the `state` object to read and update field values and errors.
86+
* You can provide custom logic for any field type (string, number, boolean, etc.) by implementing the corresponding content slot.
87+
88+
For more details, see the [usage guide](usage.md) or the [API reference](api/index.html).

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ nav:
1414
- "Overview": index.md
1515
- "Usage": usage.md
1616
- "State Management": state-management.md
17+
- "Custom Rendering": custom-rendering.md
1718
- "API reference": api/index.html
1819

1920
theme:

0 commit comments

Comments
 (0)