Browse Source

Button refactor (#3532)

[BREAKING] Buttons refactor

* Support setting single button
```js
  topBar: {
    rightButtons: {
    }
  }
```
* [BREAKING] Rename button.title to button.text

* Set TopBar default background color (white)
Guy Carmeli 6 years ago
parent
commit
70620298c6
No account linked to committer's email address

+ 6
- 0
e2e/ScreenStyle.test.js View File

153
     await elementByLabel('Start Typing').typeText(query);
153
     await elementByLabel('Start Typing').typeText(query);
154
     await expect(elementById(testIDs.SEARCH_RESULT_ITEM)).toHaveText(`Item ${query}`);
154
     await expect(elementById(testIDs.SEARCH_RESULT_ITEM)).toHaveText(`Item ${query}`);
155
   });
155
   });
156
+
157
+  test('default options should apply to all screens in stack', async () => {
158
+    await elementById(testIDs.PUSH_BUTTON).tap();
159
+    await expect(elementById(testIDs.TOP_BAR_ELEMENT)).toBeVisible();
160
+    await expect(elementById(testIDs.TOP_BAR_BUTTON)).toBeVisible();
161
+  });
156
 });
162
 });

+ 7
- 2
lib/android/app/src/main/java/com/reactnativenavigation/parse/TopBarButtons.java View File

15
         TopBarButtons result = new TopBarButtons();
15
         TopBarButtons result = new TopBarButtons();
16
         if (json == null) return result;
16
         if (json == null) return result;
17
 
17
 
18
-        result.right = Button.parseJsonArray(json.optJSONArray("rightButtons"), typefaceLoader);
19
-        result.left = Button.parseJsonArray(json.optJSONArray("leftButtons"), typefaceLoader);
18
+        result.right = parseButtons(typefaceLoader, json, "rightButtons");
19
+        result.left = parseButtons(typefaceLoader, json, "leftButtons");
20
         result.back = BackButton.parse(json.optJSONObject("backButton"));
20
         result.back = BackButton.parse(json.optJSONObject("backButton"));
21
 
21
 
22
         return result;
22
         return result;
23
     }
23
     }
24
 
24
 
25
+    @Nullable
26
+    private static ArrayList<Button> parseButtons(TypefaceLoader typefaceLoader, JSONObject json, String buttons) {
27
+        return Button.parse(json, buttons, typefaceLoader);
28
+    }
29
+
25
     public BackButton back = new BackButton();
30
     public BackButton back = new BackButton();
26
     @Nullable public ArrayList<Button> left;
31
     @Nullable public ArrayList<Button> left;
27
     @Nullable public ArrayList<Button> right;
32
     @Nullable public ArrayList<Button> right;

+ 15
- 6
lib/android/app/src/main/java/com/reactnativenavigation/parse/params/Button.java View File

18
 
18
 
19
 public class Button {
19
 public class Button {
20
     public String id;
20
     public String id;
21
-    public Text title = new NullText();
21
+    public Text text = new NullText();
22
     public Bool enabled = new NullBool();
22
     public Bool enabled = new NullBool();
23
     public Bool disableIconTint = new NullBool();
23
     public Bool disableIconTint = new NullBool();
24
     public int showAsAction;
24
     public int showAsAction;
34
     protected static Button parseJson(JSONObject json, TypefaceLoader typefaceManager) {
34
     protected static Button parseJson(JSONObject json, TypefaceLoader typefaceManager) {
35
         Button button = new Button();
35
         Button button = new Button();
36
         button.id = json.optString("id");
36
         button.id = json.optString("id");
37
-        button.title = TextParser.parse(json, "title");
37
+        button.text = TextParser.parse(json, "text");
38
         button.enabled = BoolParser.parse(json, "enabled");
38
         button.enabled = BoolParser.parse(json, "enabled");
39
         button.disableIconTint = BoolParser.parse(json, "disableIconTint");
39
         button.disableIconTint = BoolParser.parse(json, "disableIconTint");
40
         button.showAsAction = parseShowAsAction(json);
40
         button.showAsAction = parseShowAsAction(json);
53
         return button;
53
         return button;
54
     }
54
     }
55
 
55
 
56
-    public static ArrayList<Button> parseJsonArray(JSONArray jsonArray, TypefaceLoader typefaceLoader) {
56
+    public static ArrayList<Button> parse(JSONObject json, String buttonsType, TypefaceLoader typefaceLoader) {
57
         ArrayList<Button> buttons = new ArrayList<>();
57
         ArrayList<Button> buttons = new ArrayList<>();
58
-
59
-        if (jsonArray == null) {
58
+        if (!json.has(buttonsType)) {
60
             return null;
59
             return null;
61
         }
60
         }
62
 
61
 
62
+        JSONArray jsonArray = json.optJSONArray(buttonsType);
63
+        if (jsonArray != null) {
64
+            buttons.addAll(parseJsonArray(jsonArray, typefaceLoader));
65
+        } else {
66
+            buttons.add(parseJson(json.optJSONObject(buttonsType), typefaceLoader));
67
+        }
68
+        return buttons;
69
+    }
70
+
71
+    private static ArrayList<Button> parseJsonArray(JSONArray jsonArray, TypefaceLoader typefaceLoader) {
72
+        ArrayList<Button> buttons = new ArrayList<>();
63
         for (int i = 0; i < jsonArray.length(); i++) {
73
         for (int i = 0; i < jsonArray.length(); i++) {
64
             JSONObject json = jsonArray.optJSONObject(i);
74
             JSONObject json = jsonArray.optJSONObject(i);
65
             Button button = Button.parseJson(json, typefaceLoader);
75
             Button button = Button.parseJson(json, typefaceLoader);
66
             buttons.add(button);
76
             buttons.add(button);
67
         }
77
         }
68
-
69
         return buttons;
78
         return buttons;
70
     }
79
     }
71
 
80
 

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/presentation/StackOptionsPresenter.java View File

92
         topBar.setBorderHeight(options.borderHeight.get(0d));
92
         topBar.setBorderHeight(options.borderHeight.get(0d));
93
         topBar.setBorderColor(options.borderColor.get(DEFAULT_BORDER_COLOR));
93
         topBar.setBorderColor(options.borderColor.get(DEFAULT_BORDER_COLOR));
94
 
94
 
95
-        topBar.setBackgroundColor(options.background.color);
95
+        topBar.setBackgroundColor(options.background.color.get(Color.WHITE));
96
         topBar.setBackgroundComponent(options.background.component);
96
         topBar.setBackgroundComponent(options.background.component);
97
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
97
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
98
 
98
 
186
         if (options.subtitle.fontSize.hasValue()) topBar.setSubtitleFontSize(options.subtitle.fontSize.get());
186
         if (options.subtitle.fontSize.hasValue()) topBar.setSubtitleFontSize(options.subtitle.fontSize.get());
187
         if (options.subtitle.fontFamily != null) topBar.setSubtitleFontFamily(options.subtitle.fontFamily);
187
         if (options.subtitle.fontFamily != null) topBar.setSubtitleFontFamily(options.subtitle.fontFamily);
188
 
188
 
189
-        if (options.background.color.hasValue()) topBar.setBackgroundColor(options.background.color);
189
+        if (options.background.color.hasValue()) topBar.setBackgroundColor(options.background.color.get());
190
 
190
 
191
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
191
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
192
 
192
 

+ 3
- 3
lib/android/app/src/main/java/com/reactnativenavigation/utils/ButtonOptionsPresenter.java View File

41
     }
41
     }
42
 
42
 
43
     public void setFontSize(MenuItem menuItem) {
43
     public void setFontSize(MenuItem menuItem) {
44
-        SpannableString spanString = new SpannableString(button.title.get());
44
+        SpannableString spanString = new SpannableString(button.text.get());
45
         if (this.button.fontSize.hasValue())
45
         if (this.button.fontSize.hasValue())
46
             spanString.setSpan(
46
             spanString.setSpan(
47
                     new AbsoluteSizeSpan(button.fontSize.get(), true),
47
                     new AbsoluteSizeSpan(button.fontSize.get(), true),
48
                     0,
48
                     0,
49
-                    button.title.get().length(),
49
+                    button.text.get().length(),
50
                     Spannable.SPAN_INCLUSIVE_INCLUSIVE
50
                     Spannable.SPAN_INCLUSIVE_INCLUSIVE
51
             );
51
             );
52
         menuItem.setTitleCondensed(spanString);
52
         menuItem.setTitleCondensed(spanString);
76
     @NonNull
76
     @NonNull
77
     private ArrayList<View> findActualTextViewInMenu() {
77
     private ArrayList<View> findActualTextViewInMenu() {
78
         ArrayList<View> outViews = new ArrayList<>();
78
         ArrayList<View> outViews = new ArrayList<>();
79
-        toolbar.findViewsWithText(outViews, button.title.get(), View.FIND_VIEWS_WITH_TEXT);
79
+        toolbar.findViewsWithText(outViews, button.text.get(), View.FIND_VIEWS_WITH_TEXT);
80
         return outViews;
80
         return outViews;
81
     }
81
     }
82
 
82
 

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TopBarButtonController.java View File

99
     }
99
     }
100
 
100
 
101
     public void addToMenu(Toolbar toolbar, int position) {
101
     public void addToMenu(Toolbar toolbar, int position) {
102
-        MenuItem menuItem = toolbar.getMenu().add(0, position, position, button.title.get(""));
102
+        MenuItem menuItem = toolbar.getMenu().add(0, position, position, button.text.get(""));
103
         menuItem.setShowAsAction(button.showAsAction);
103
         menuItem.setShowAsAction(button.showAsAction);
104
         menuItem.setEnabled(button.enabled.isTrueOrUndefined());
104
         menuItem.setEnabled(button.enabled.isTrueOrUndefined());
105
         menuItem.setOnMenuItemClickListener(this);
105
         menuItem.setOnMenuItemClickListener(this);
144
             ActionMenuView buttonsLayout = ViewUtils.findChildByClass(toolbar, ActionMenuView.class);
144
             ActionMenuView buttonsLayout = ViewUtils.findChildByClass(toolbar, ActionMenuView.class);
145
             List<TextView> buttons = ViewUtils.findChildrenByClass(buttonsLayout, TextView.class);
145
             List<TextView> buttons = ViewUtils.findChildrenByClass(buttonsLayout, TextView.class);
146
             for (TextView view : buttons) {
146
             for (TextView view : buttons) {
147
-                if (button.title.hasValue() && button.title.get().equals(view.getText().toString())) {
147
+                if (button.text.hasValue() && button.text.get().equals(view.getText().toString())) {
148
                     view.setTag(testId.get());
148
                     view.setTag(testId.get());
149
                 } else if (button.icon.hasValue() && ArrayUtils.contains(view.getCompoundDrawables(), icon)) {
149
                 } else if (button.icon.hasValue() && ArrayUtils.contains(view.getCompoundDrawables(), icon)) {
150
                     view.setTag(testId.get());
150
                     view.setTag(testId.get());

+ 0
- 5
lib/android/app/src/main/java/com/reactnativenavigation/views/topbar/TopBar.java View File

225
         titleBar.setRightButtons(rightButtons);
225
         titleBar.setRightButtons(rightButtons);
226
     }
226
     }
227
 
227
 
228
-    public void setBackgroundColor(Color color) {
229
-        if (!color.hasValue()) return;
230
-        setBackgroundColor(color.get());
231
-    }
232
-
233
     public void setElevation(Fraction elevation) {
228
     public void setElevation(Fraction elevation) {
234
         if (elevation.hasValue() &&
229
         if (elevation.hasValue() &&
235
             Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
230
             Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&

+ 1
- 1
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackOptionsPresenterTest.java View File

151
             verify(topBar, times(t)).setSubtitle(any());
151
             verify(topBar, times(t)).setSubtitle(any());
152
         }
152
         }
153
         verify(topBar, times(t)).setTitleComponent(any());
153
         verify(topBar, times(t)).setTitleComponent(any());
154
-        verify(topBar, times(t)).setBackgroundColor(any());
154
+        verify(topBar, times(t)).setBackgroundColor(anyInt());
155
         verify(topBar, times(t)).setTitleTextColor(anyInt());
155
         verify(topBar, times(t)).setTitleTextColor(anyInt());
156
         verify(topBar, times(t)).setTitleFontSize(anyDouble());
156
         verify(topBar, times(t)).setTitleFontSize(anyDouble());
157
         verify(topBar, times(t)).setTitleTypeface(any());
157
         verify(topBar, times(t)).setTitleTypeface(any());

+ 3
- 3
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TitleBarTest.java View File

66
 
66
 
67
         textButton = new Button();
67
         textButton = new Button();
68
         textButton.id = "textButton";
68
         textButton.id = "textButton";
69
-        textButton.title = new Text("Btn");
69
+        textButton.text = new Text("Btn");
70
 
70
 
71
         customButton = new Button();
71
         customButton = new Button();
72
         customButton.id = "customBtn";
72
         customButton.id = "customBtn";
78
     public void setButton_setsTextButton() {
78
     public void setButton_setsTextButton() {
79
         uut.setRightButtons(rightButtons(textButton));
79
         uut.setRightButtons(rightButtons(textButton));
80
         uut.setLeftButtons(leftButton(leftButton));
80
         uut.setLeftButtons(leftButton(leftButton));
81
-        assertThat(uut.getMenu().getItem(0).getTitle()).isEqualTo(textButton.title.get());
81
+        assertThat(uut.getMenu().getItem(0).getTitle()).isEqualTo(textButton.text.get());
82
     }
82
     }
83
 
83
 
84
     @Test
84
     @Test
141
     public void setRightButtons_buttonsAreAddedInReverseOrderToMatchOrderOnIOs() {
141
     public void setRightButtons_buttonsAreAddedInReverseOrderToMatchOrderOnIOs() {
142
         uut.setLeftButtons(new ArrayList<>());
142
         uut.setLeftButtons(new ArrayList<>());
143
         uut.setRightButtons(rightButtons(textButton, customButton));
143
         uut.setRightButtons(rightButtons(textButton, customButton));
144
-        assertThat(uut.getMenu().getItem(1).getTitle()).isEqualTo(textButton.title.get());
144
+        assertThat(uut.getMenu().getItem(1).getTitle()).isEqualTo(textButton.text.get());
145
     }
145
     }
146
 
146
 
147
     @Test
147
     @Test

+ 1
- 1
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopBarButtonControllerTest.java View File

159
 
159
 
160
     private void setTextButton() {
160
     private void setTextButton() {
161
         button.id = "btn1";
161
         button.id = "btn1";
162
-        button.title = new Text("Button");
162
+        button.text = new Text("Button");
163
         button.fontFamily = Typeface.MONOSPACE;
163
         button.fontFamily = Typeface.MONOSPACE;
164
         button.showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
164
         button.showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
165
     }
165
     }

+ 2
- 2
lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarTest.java View File

62
         ArrayList<Button> result = new ArrayList<>();
62
         ArrayList<Button> result = new ArrayList<>();
63
         Button leftButton = new Button();
63
         Button leftButton = new Button();
64
         leftButton.id = "leftButton";
64
         leftButton.id = "leftButton";
65
-        leftButton.title = new Text("");
65
+        leftButton.text = new Text("");
66
         result.add(spy(leftButton));
66
         result.add(spy(leftButton));
67
         return result;
67
         return result;
68
     }
68
     }
72
         for (int i = 0; i < 2; i++) {
72
         for (int i = 0; i < 2; i++) {
73
             Button button = new Button();
73
             Button button = new Button();
74
             button.id = "rightButtons" + i;
74
             button.id = "rightButtons" + i;
75
-            button.title = new Text("btn" + i);
75
+            button.text = new Text("btn" + i);
76
             button.showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
76
             button.showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
77
             result.add(spy(button));
77
             result.add(spy(button));
78
         }
78
         }

+ 5
- 5
playground/src/screens/OptionsScreen.js View File

75
           {
75
           {
76
             id: BUTTON_ONE,
76
             id: BUTTON_ONE,
77
             testID: BUTTON_ONE,
77
             testID: BUTTON_ONE,
78
-            title: 'One',
78
+            text: 'One',
79
             fontFamily: 'HelveticaNeue-Italic',
79
             fontFamily: 'HelveticaNeue-Italic',
80
             fontSize: 28,
80
             fontSize: 28,
81
             color: 'red'
81
             color: 'red'
85
           id: BUTTON_LEFT,
85
           id: BUTTON_LEFT,
86
           testID: BUTTON_LEFT,
86
           testID: BUTTON_LEFT,
87
           icon: require('../../img/navicon_add.png'),
87
           icon: require('../../img/navicon_add.png'),
88
-          title: 'Left',
88
+          text: 'Left',
89
           color: 'purple'
89
           color: 'purple'
90
         }
90
         }
91
       },
91
       },
144
           rightButtons: [{
144
           rightButtons: [{
145
             id: BUTTON_TWO,
145
             id: BUTTON_TWO,
146
             testID: BUTTON_TWO,
146
             testID: BUTTON_TWO,
147
-            title: 'Two',
147
+            text: 'Two',
148
             icon: require('../../img/navicon_add.png'),
148
             icon: require('../../img/navicon_add.png'),
149
             disableIconTint: true,
149
             disableIconTint: true,
150
             showAsAction: 'ifRoom',
150
             showAsAction: 'ifRoom',
161
           rightButtons: [{
161
           rightButtons: [{
162
             id: BUTTON_ONE,
162
             id: BUTTON_ONE,
163
             testID: BUTTON_ONE,
163
             testID: BUTTON_ONE,
164
-            title: 'One',
164
+            text: 'One',
165
             color: 'red'
165
             color: 'red'
166
           }],
166
           }],
167
           leftButtons: [{
167
           leftButtons: [{
168
             id: BUTTON_LEFT,
168
             id: BUTTON_LEFT,
169
             testID: BUTTON_LEFT,
169
             testID: BUTTON_LEFT,
170
             icon: require('../../img/navicon_add.png'),
170
             icon: require('../../img/navicon_add.png'),
171
-            title: 'Left',
171
+            text: 'Left',
172
             color: 'purple'
172
             color: 'purple'
173
           }]
173
           }]
174
         }
174
         }

+ 6
- 1
playground/src/screens/PushedScreen.js View File

17
         drawBehind: true
17
         drawBehind: true
18
       },
18
       },
19
       topBar: {
19
       topBar: {
20
-        testID: testIDs.TOP_BAR_ELEMENT
20
+        testID: testIDs.TOP_BAR_ELEMENT,
21
+        rightButtons: {
22
+          id: 'singleBtn',
23
+          text: 'single',
24
+          testID: testIDs.TOP_BAR_BUTTON
25
+        }
21
       },
26
       },
22
       layout: {
27
       layout: {
23
         backgroundColor: '#f5fcff'
28
         backgroundColor: '#f5fcff'

+ 1
- 0
playground/src/testIDs.js View File

38
   DYNAMIC_OPTIONS_BUTTON: `DYNAMIC_OPTIONS_BUTTON`,
38
   DYNAMIC_OPTIONS_BUTTON: `DYNAMIC_OPTIONS_BUTTON`,
39
   SHOW_TOP_BAR_BUTTON: `SHOW_TOP_BAR_BUTTON`,
39
   SHOW_TOP_BAR_BUTTON: `SHOW_TOP_BAR_BUTTON`,
40
   HIDE_TOP_BAR_BUTTON: `HIDE_TOP_BAR_BUTTON`,
40
   HIDE_TOP_BAR_BUTTON: `HIDE_TOP_BAR_BUTTON`,
41
+  TOP_BAR_BUTTON: `TOP_BAR_BUTTON`,
41
   SCROLLVIEW_SCREEN_BUTTON: `SCROLLVIEW_SCREEN_BUTTON`,
42
   SCROLLVIEW_SCREEN_BUTTON: `SCROLLVIEW_SCREEN_BUTTON`,
42
   HIDE_FAB: `HIDE_FAB`,
43
   HIDE_FAB: `HIDE_FAB`,
43
   SHOW_SNACKBAR_BUTTON: `SHOW_SNACKBAR_BUTTON`,
44
   SHOW_SNACKBAR_BUTTON: `SHOW_SNACKBAR_BUTTON`,