Browse Source

Added basic ZefyrField widget

Anatoly Pulyaevskiy 6 years ago
parent
commit
b63232641f

+ 3
- 0
packages/zefyr/CHANGELOG.md View File

@@ -6,8 +6,11 @@ layouts, like forms with multiple input fields.
6 6
 It is now required to always wrap `ZefyrEditor` with an instance of this new widget. See examples
7 7
 and readme for more details.
8 8
 
9
+There is also new `ZefyrField` widget which integrates Zefyr with material design decorations.
10
+
9 11
 * Breaking change: `ZefyrEditor` requires an ancestor `ZefyrScaffold`.
10 12
 * Exposed `ZefyrEditor.physics` property to allow customization of `ScrollPhysics`.
13
+* Added basic `ZefyrField` widget.
11 14
 
12 15
 ## 0.2.0
13 16
 

+ 11
- 29
packages/zefyr/example/lib/src/form.dart View File

@@ -17,21 +17,8 @@ class _FormEmbeddedScreenState extends State<FormEmbeddedScreen> {
17 17
     final form = ListView(
18 18
       children: <Widget>[
19 19
         TextField(decoration: InputDecoration(labelText: 'Name')),
20
-        TextField(decoration: InputDecoration(labelText: 'Email')),
21
-        TextField(
22
-          decoration: InputDecoration(labelText: 'Regular multiline text'),
23
-          maxLines: 5,
24
-        ),
25
-        Container(
26
-          padding: EdgeInsets.only(top: 16.0),
27
-          child: Text(
28
-            'Zefyr rich text',
29
-            style: TextStyle(color: Colors.black54, fontSize: 16.0),
30
-          ),
31
-          alignment: Alignment.centerLeft,
32
-        ),
33
-
34 20
         buildEditor(),
21
+        TextField(decoration: InputDecoration(labelText: 'Email')),
35 22
       ],
36 23
     );
37 24
 
@@ -62,21 +49,16 @@ class _FormEmbeddedScreenState extends State<FormEmbeddedScreen> {
62 49
       ),
63 50
     );
64 51
 
65
-    return Container(
66
-      margin: EdgeInsets.symmetric(vertical: 8.0),
67
-      constraints: BoxConstraints.tightFor(height: 300.0),
68
-      decoration:
69
-          BoxDecoration(border: Border.all(color: Colors.grey.shade400)),
70
-      child: ZefyrTheme(
71
-        data: theme,
72
-        child: ZefyrEditor(
73
-          padding: EdgeInsets.all(8.0),
74
-          controller: _controller,
75
-          focusNode: _focusNode,
76
-          autofocus: false,
77
-          imageDelegate: new CustomImageDelegate(),
78
-          physics: ClampingScrollPhysics(),
79
-        ),
52
+    return ZefyrTheme(
53
+      data: theme,
54
+      child: ZefyrField(
55
+        height: 200.0,
56
+        decoration: InputDecoration(labelText: 'Description'),
57
+        controller: _controller,
58
+        focusNode: _focusNode,
59
+        autofocus: false,
60
+        imageDelegate: new CustomImageDelegate(),
61
+        physics: ClampingScrollPhysics(),
80 62
       ),
81 63
     );
82 64
   }

+ 86
- 0
packages/zefyr/lib/src/widgets/field.dart View File

@@ -0,0 +1,86 @@
1
+import 'package:flutter/material.dart';
2
+
3
+import 'controller.dart';
4
+import 'editor.dart';
5
+import 'image.dart';
6
+import 'toolbar.dart';
7
+
8
+/// Zefyr editor with material design decorations.
9
+class ZefyrField extends StatefulWidget {
10
+  /// Decoration to paint around this editor.
11
+  final InputDecoration decoration;
12
+
13
+  /// Height of this editor field.
14
+  final double height;
15
+  final ZefyrController controller;
16
+  final FocusNode focusNode;
17
+  final bool autofocus;
18
+  final bool enabled;
19
+  final ZefyrToolbarDelegate toolbarDelegate;
20
+  final ZefyrImageDelegate imageDelegate;
21
+  final ScrollPhysics physics;
22
+
23
+  const ZefyrField({
24
+    Key key,
25
+    this.decoration,
26
+    this.height,
27
+    this.controller,
28
+    this.focusNode,
29
+    this.autofocus: false,
30
+    this.enabled,
31
+    this.toolbarDelegate,
32
+    this.imageDelegate,
33
+    this.physics,
34
+  }) : super(key: key);
35
+
36
+  @override
37
+  _ZefyrFieldState createState() => _ZefyrFieldState();
38
+}
39
+
40
+class _ZefyrFieldState extends State<ZefyrField> {
41
+  @override
42
+  Widget build(BuildContext context) {
43
+    Widget child = ZefyrEditor(
44
+      padding: EdgeInsets.symmetric(vertical: 6.0),
45
+      controller: widget.controller,
46
+      focusNode: widget.focusNode,
47
+      autofocus: widget.autofocus,
48
+      enabled: widget.enabled ?? true,
49
+      toolbarDelegate: widget.toolbarDelegate,
50
+      imageDelegate: widget.imageDelegate,
51
+      physics: widget.physics,
52
+    );
53
+
54
+    if (widget.height != null) {
55
+      child = ConstrainedBox(
56
+        constraints: BoxConstraints.tightFor(height: widget.height),
57
+        child: child,
58
+      );
59
+    }
60
+
61
+    return AnimatedBuilder(
62
+      animation:
63
+          Listenable.merge(<Listenable>[widget.focusNode, widget.controller]),
64
+      builder: (BuildContext context, Widget child) {
65
+        return InputDecorator(
66
+          decoration: _getEffectiveDecoration(),
67
+          isFocused: widget.focusNode.hasFocus,
68
+          isEmpty: widget.controller.document.length == 1,
69
+          child: child,
70
+        );
71
+      },
72
+      child: child,
73
+    );
74
+  }
75
+
76
+  InputDecoration _getEffectiveDecoration() {
77
+    final InputDecoration effectiveDecoration =
78
+        (widget.decoration ?? const InputDecoration())
79
+            .applyDefaults(Theme.of(context).inputDecorationTheme)
80
+            .copyWith(
81
+              enabled: widget.enabled ?? true,
82
+            );
83
+
84
+    return effectiveDecoration;
85
+  }
86
+}

+ 1
- 1
packages/zefyr/lib/zefyr.dart View File

@@ -15,6 +15,7 @@ export 'src/widgets/common.dart';
15 15
 export 'src/widgets/controller.dart';
16 16
 export 'src/widgets/editable_text.dart';
17 17
 export 'src/widgets/editor.dart';
18
+export 'src/widgets/field.dart';
18 19
 export 'src/widgets/horizontal_rule.dart';
19 20
 export 'src/widgets/image.dart';
20 21
 export 'src/widgets/list.dart';
@@ -24,4 +25,3 @@ export 'src/widgets/scaffold.dart';
24 25
 export 'src/widgets/selection.dart' hide SelectionHandleDriver;
25 26
 export 'src/widgets/theme.dart';
26 27
 export 'src/widgets/toolbar.dart';
27
-//export 'src/widgets/render_context.dart';