Skip to content

Commit ca27d62

Browse files
authored
Feature: custom input in demo app (#1574)
1 parent f73b715 commit ca27d62

3 files changed

Lines changed: 134 additions & 3 deletions

File tree

demo_app/lib/screens/home.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:demo_app/screens/font_size.dart';
55
import 'package:demo_app/screens/golden.dart';
66
import 'package:demo_app/screens/hello_world.dart';
77
import 'package:demo_app/screens/hello_world_core.dart';
8+
import 'package:demo_app/screens/html_playground.dart';
89
import 'package:demo_app/screens/huge_html.dart';
910
import 'package:demo_app/screens/iframe.dart';
1011
import 'package:demo_app/screens/img.dart';
@@ -35,6 +36,7 @@ class HomeScreen extends StatelessWidget {
3536
'Smilie': () => const SmilieScreen(),
3637
'Wordpress': () => const WordpressScreen(),
3738
'Text Shadow': () => const TextShadowScreen(),
39+
'HTML Playground': () => const HtmlPlaygroundScreen(),
3840
};
3941

4042
const HomeScreen({super.key});
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import 'package:demo_app/widgets/popup_menu.dart';
2+
import 'package:demo_app/widgets/selection_area.dart';
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
5+
6+
const _kInitialHtml = '''
7+
<h1>Hello, HTML Playground!</h1>
8+
<p>Edit the HTML on the <strong>left</strong> (or <em>top</em>) to see it rendered here.</p>
9+
<ul>
10+
<li>Supports <strong>bold</strong> and <em>italic</em></li>
11+
<li>And <a href="https://flutter.dev">links</a></li>
12+
</ul>''';
13+
14+
class HtmlPlaygroundScreen extends StatefulWidget {
15+
const HtmlPlaygroundScreen({super.key});
16+
17+
@override
18+
State<HtmlPlaygroundScreen> createState() => _HtmlPlaygroundScreenState();
19+
}
20+
21+
class _HtmlPlaygroundScreenState extends State<HtmlPlaygroundScreen> {
22+
late final TextEditingController _controller;
23+
24+
@override
25+
void initState() {
26+
super.initState();
27+
_controller = TextEditingController(text: _kInitialHtml);
28+
}
29+
30+
@override
31+
void dispose() {
32+
_controller.dispose();
33+
super.dispose();
34+
}
35+
36+
@override
37+
Widget build(BuildContext context) => SelectionAreaScaffold(
38+
appBar: AppBar(
39+
title: const Text('HTML Playground'),
40+
actions: const [PopupMenu(toggleIsSelectable: true)],
41+
),
42+
body: LayoutBuilder(
43+
builder: (context, constraints) {
44+
final isWide = constraints.maxWidth > constraints.maxHeight;
45+
46+
final inputPane = _InputPane(controller: _controller);
47+
final previewPane = _PreviewPane(controller: _controller);
48+
49+
if (isWide) {
50+
return Row(
51+
crossAxisAlignment: CrossAxisAlignment.stretch,
52+
children: [
53+
Expanded(child: inputPane),
54+
const VerticalDivider(width: 1),
55+
Expanded(child: previewPane),
56+
],
57+
);
58+
} else {
59+
return Column(
60+
children: [
61+
Expanded(child: inputPane),
62+
const Divider(height: 1),
63+
Expanded(child: previewPane),
64+
],
65+
);
66+
}
67+
},
68+
),
69+
);
70+
}
71+
72+
class _InputPane extends StatelessWidget {
73+
final TextEditingController controller;
74+
75+
const _InputPane({required this.controller});
76+
77+
@override
78+
Widget build(BuildContext context) => Padding(
79+
padding: const EdgeInsets.all(8),
80+
child: TextField(
81+
controller: controller,
82+
maxLines: null,
83+
expands: true,
84+
textAlignVertical: TextAlignVertical.top,
85+
style: const TextStyle(fontFamily: 'monospace', fontSize: 13),
86+
decoration: const InputDecoration(
87+
border: OutlineInputBorder(),
88+
labelText: 'HTML input',
89+
alignLabelWithHint: true,
90+
),
91+
),
92+
);
93+
}
94+
95+
class _PreviewPane extends StatefulWidget {
96+
final TextEditingController controller;
97+
98+
const _PreviewPane({required this.controller});
99+
100+
@override
101+
State<_PreviewPane> createState() => _PreviewPaneState();
102+
}
103+
104+
class _PreviewPaneState extends State<_PreviewPane> {
105+
late String _html;
106+
107+
@override
108+
void initState() {
109+
super.initState();
110+
_html = widget.controller.text;
111+
widget.controller.addListener(_onHtmlChanged);
112+
}
113+
114+
@override
115+
void dispose() {
116+
widget.controller.removeListener(_onHtmlChanged);
117+
super.dispose();
118+
}
119+
120+
void _onHtmlChanged() {
121+
setState(() => _html = widget.controller.text);
122+
}
123+
124+
@override
125+
Widget build(BuildContext context) => SingleChildScrollView(
126+
padding: const EdgeInsets.all(8),
127+
child: HtmlWidget(_html),
128+
);
129+
}

demo_app/pubspec.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,14 @@ packages:
302302
path: "../packages/enhanced"
303303
relative: true
304304
source: path
305-
version: "0.17.1"
305+
version: "0.17.2"
306306
flutter_widget_from_html_core:
307307
dependency: "direct main"
308308
description:
309309
path: "../packages/core"
310310
relative: true
311311
source: path
312-
version: "0.17.0"
312+
version: "0.17.2"
313313
frontend_server_client:
314314
dependency: transitive
315315
description:
@@ -359,7 +359,7 @@ packages:
359359
path: "../packages/fwfh_webview"
360360
relative: true
361361
source: path
362-
version: "0.15.6"
362+
version: "0.15.7"
363363
glob:
364364
dependency: transitive
365365
description:

0 commit comments

Comments
 (0)