Skip to content

Commit 600bc72

Browse files
committed
feat: add custom style authoring and component stream demo gif
1 parent efdf7d5 commit 600bc72

7 files changed

Lines changed: 913 additions & 10 deletions

File tree

README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Quick links:
2727
- Dynamic prop resolution (`$state`, `$item`, `$index`, `$cond`)
2828
- Visibility and repeat support
2929
- Style presets and style-aware prompt generation
30+
- Custom style creation from JSON tokens
3031
- JSONL streaming patch compiler for progressive UI updates
3132

3233
## Install
@@ -39,6 +40,7 @@ flutter pub add flutter_json_render
3940

4041
- [Core Concepts](#core-concepts)
4142
- [Quick Start](#quick-start)
43+
- [Custom Styles](#custom-styles)
4244
- [Stream JSONL Patches](#stream-jsonl-patches)
4345
- [Validate Specs](#validate-specs)
4446
- [Built-In Components](#built-in-components)
@@ -164,6 +166,45 @@ final prompt = catalog.prompt(
164166
);
165167
```
166168

169+
## Custom Styles
170+
171+
`JsonStyleDefinition` now supports JSON round-tripping and token maps:
172+
173+
```dart
174+
final customStyle = JsonStyleDefinition.fromJson({
175+
'displayName': 'Aurora',
176+
'description': 'Cool dark surface with cyan accents',
177+
'guidance': 'Prefer high contrast and compact spacing.',
178+
'tokens': {
179+
'accent': '#22D3EE',
180+
'panelBackground': '#0B1220',
181+
'textPrimary': '#E0F2FE',
182+
},
183+
});
184+
185+
final catalog = baseCatalog.withStyle('aurora', customStyle);
186+
```
187+
188+
Bulk import style maps from API/LLM output:
189+
190+
```dart
191+
final catalog = baseCatalog.withStylesFromJson({
192+
'aurora': {
193+
'displayName': 'Aurora',
194+
'description': 'Cool dark surface with cyan accents',
195+
'guidance': 'Prefer high contrast and compact spacing.',
196+
'tokens': {
197+
'accent': '#22D3EE',
198+
'panelBackground': '#0B1220',
199+
'textPrimary': '#E0F2FE',
200+
},
201+
},
202+
});
203+
```
204+
205+
See full style authoring guide:
206+
- [`docs/custom-style-guide.md`](docs/custom-style-guide.md)
207+
167208
## Stream JSONL Patches
168209

169210
```dart
@@ -240,6 +281,8 @@ Included scenarios:
240281
- Dynamic props via `$cond`
241282
- Async action flow
242283
- Streamed JSONL patch simulation
284+
- Chat-like stream build-up
285+
- Streamed multi-component build-up (`Text`, `Row`, `Column`, `Container`, `Center`, `SizedBox`, `Button`, custom components)
243286

244287
The example includes a `Style Preset` dropdown and supports startup style selection:
245288

@@ -248,12 +291,43 @@ cd example
248291
flutter run --dart-define=STYLE_PRESET=midnight
249292
```
250293

294+
You can also add a custom style at runtime:
295+
296+
- Click `Add Custom Style` and paste a style JSON object.
297+
- Or boot with `CUSTOM_STYLE_JSON`:
298+
299+
```bash
300+
cd example
301+
flutter run \
302+
--dart-define=STYLE_PRESET=sunset \
303+
--dart-define=CUSTOM_STYLE_JSON='{"id":"aurora","base":"midnight","displayName":"Aurora","description":"Deep blue surface with bright cyan accents.","guidance":"Use high contrast and cool accent colors.","tokens":{"accent":"#22D3EE","panelBackground":"#0B1220","textPrimary":"#E0F2FE"}}'
304+
```
305+
251306
### Style Preset Screenshots
252307

253308
| clean | midnight | sunset |
254309
|---|---|---|
255310
| ![clean](https://raw.githubusercontent.com/Dev-Beom/flutter-json-render/main/assets/screenshots/example-style-clean.png) | ![midnight](https://raw.githubusercontent.com/Dev-Beom/flutter-json-render/main/assets/screenshots/example-style-midnight.png) | ![sunset](https://raw.githubusercontent.com/Dev-Beom/flutter-json-render/main/assets/screenshots/example-style-sunset.png) |
256311

312+
### Streaming LLM Output Demo (GIF)
313+
314+
JSONL patch stream progressively builds a component-rich interface:
315+
316+
![stream-demo](https://raw.githubusercontent.com/Dev-Beom/flutter-json-render/main/assets/gifs/component-stream-render.gif)
317+
318+
Replay the same capture scenario locally:
319+
320+
```bash
321+
cd example
322+
flutter run \
323+
--dart-define=STYLE_PRESET=sunset \
324+
--dart-define=SCENARIO=component_stream \
325+
--dart-define=AUTO_RUN_STREAM=true \
326+
--dart-define=AUTO_RUN_DELAY_MS=2200 \
327+
--dart-define=STREAM_STEP_DELAY_MS=620 \
328+
--dart-define=CAPTURE_MODE=true
329+
```
330+
257331
## pub.dev Release Checklist
258332

259333
```bash
1000 KB
Loading

docs/custom-style-guide.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Custom Style Guide
2+
3+
This guide explains how to create custom styles for `flutter_json_render`.
4+
5+
## 1) Style Data Model
6+
7+
Use `JsonStyleDefinition` for style metadata and optional token payload.
8+
9+
```dart
10+
const style = JsonStyleDefinition(
11+
displayName: 'Aurora',
12+
description: 'Deep blue surface with cyan accents.',
13+
guidance: 'Use high contrast and cool color highlights.',
14+
tokens: <String, dynamic>{
15+
'accent': '#22D3EE',
16+
'panelBackground': '#0B1220',
17+
'textPrimary': '#E0F2FE',
18+
},
19+
);
20+
```
21+
22+
## 2) Create Styles from JSON
23+
24+
```dart
25+
final style = JsonStyleDefinition.fromJson(<String, dynamic>{
26+
'displayName': 'Aurora',
27+
'description': 'Deep blue surface with cyan accents.',
28+
'guidance': 'Use high contrast and cool color highlights.',
29+
'tokens': <String, dynamic>{
30+
'accent': '#22D3EE',
31+
'panelBackground': '#0B1220',
32+
'textPrimary': '#E0F2FE',
33+
},
34+
});
35+
```
36+
37+
`tokens` is intentionally open-ended so your renderer can define its own token contract.
38+
39+
## 3) Register Custom Styles
40+
41+
Single style:
42+
43+
```dart
44+
final catalog = baseCatalog.withStyle('aurora', style);
45+
```
46+
47+
Batch style import:
48+
49+
```dart
50+
final catalog = baseCatalog.withStylesFromJson(<String, dynamic>{
51+
'aurora': <String, dynamic>{
52+
'displayName': 'Aurora',
53+
'description': 'Deep blue surface with cyan accents.',
54+
'guidance': 'Use high contrast and cool color highlights.',
55+
'tokens': <String, dynamic>{
56+
'accent': '#22D3EE',
57+
'panelBackground': '#0B1220',
58+
'textPrimary': '#E0F2FE',
59+
},
60+
},
61+
'warm': <String, dynamic>{
62+
'displayName': 'Warm',
63+
'description': 'Cream cards with orange emphasis.',
64+
'guidance': 'Use warm neutrals and soft border contrast.',
65+
'tokens': <String, dynamic>{
66+
'accent': '#EA580C',
67+
'panelBackground': '#FFF7ED',
68+
'textPrimary': '#7C2D12',
69+
},
70+
},
71+
});
72+
```
73+
74+
## 4) Prompting with Selected Style
75+
76+
```dart
77+
final systemPrompt = catalog.prompt(
78+
options: const JsonPromptOptions(
79+
includeStyles: true,
80+
selectedStyleId: 'aurora',
81+
),
82+
);
83+
```
84+
85+
This makes LLM generation style-aware while still restricting output to your catalog.
86+
87+
## 5) Example App Runtime Injection
88+
89+
The example app supports runtime custom style injection with `CUSTOM_STYLE_JSON`:
90+
91+
```bash
92+
cd example
93+
flutter run \
94+
--dart-define=STYLE_PRESET=sunset \
95+
--dart-define=CUSTOM_STYLE_JSON='{"id":"aurora","base":"midnight","displayName":"Aurora","description":"Deep blue surface with bright cyan accents.","guidance":"Use high contrast and cool accent colors.","tokens":{"accent":"#22D3EE","panelBackground":"#0B1220","textPrimary":"#E0F2FE"}}'
96+
```
97+
98+
You can also apply JSON from the in-app `Add Custom Style` dialog.

0 commit comments

Comments
 (0)