|
| 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). |
0 commit comments