소스 검색

Allow to update props for a specific component (#5612)

This commit adds support to update props of screen or custom button/title via the mergeOptions api.

```js
Navigation.mergeOptions('myComponentId', {
  passProps: {
    text: 'new value'
  }
});
```
Tal Magen 5 년 전
부모
커밋
291f16177d

+ 1
- 0
.gitignore 파일 보기

1
 dist
1
 dist
2
 .vscode/
2
 .vscode/
3
 package-lock.json
3
 package-lock.json
4
+.history/
4
 
5
 
5
 ############
6
 ############
6
 # Node
7
 # Node

+ 2
- 2
docs/api/Store.md 파일 보기

32
 
32
 
33
 ---
33
 ---
34
 
34
 
35
-## cleanId
35
+## clearComponent
36
 
36
 
37
-`cleanId(id: string): void`
37
+`clearComponent(id: string): void`
38
 
38
 
39
 [source](https://github.com/wix/react-native-navigation/blob/v2/lib/src/components/Store.ts#L23)
39
 [source](https://github.com/wix/react-native-navigation/blob/v2/lib/src/components/Store.ts#L23)
40
 
40
 

+ 48
- 0
e2e/Buttons.test.js 파일 보기

1
+const Utils = require('./Utils');
2
+const TestIDs = require('../playground/src/testIDs');
3
+
4
+const { elementById, elementByLabel } = Utils;
5
+
6
+describe('Buttons', () => {
7
+  beforeEach(async () => {
8
+    await device.relaunchApp();
9
+    await elementById(TestIDs.OPTIONS_TAB).tap();
10
+    await elementById(TestIDs.GOTO_BUTTONS_SCREEN).tap();
11
+  });
12
+
13
+  it('sets right buttons', async () => {
14
+    await expect(elementById(TestIDs.BUTTON_ONE)).toBeVisible();
15
+    await expect(elementById(TestIDs.ROUND_BUTTON)).toBeVisible();
16
+  });
17
+
18
+  it('set left buttons', async () => {
19
+    await expect(elementById(TestIDs.LEFT_BUTTON)).toBeVisible();
20
+  });
21
+
22
+  it('pass props to custom button component', async () => {
23
+    await expect(elementByLabel('Two')).toExist();
24
+  });
25
+
26
+  it('pass props to custom button component should exist after push pop', async () => {
27
+    await expect(elementByLabel('Two')).toExist();
28
+    await elementById(TestIDs.PUSH_BTN).tap();
29
+    await elementById(TestIDs.POP_BTN).tap();
30
+    await expect(elementByLabel('Two')).toExist();
31
+  });
32
+
33
+  it('custom button is clickable', async () => {
34
+    await elementByLabel('Two').tap();
35
+    await expect(elementByLabel('Thanks for that :)')).toExist();
36
+  });
37
+
38
+  it(':ios: Reseting buttons should unmount button react view', async () => {
39
+    await elementById(TestIDs.SHOW_LIFECYCLE_BTN).tap();
40
+    await elementById(TestIDs.RESET_BUTTONS).tap();
41
+    await expect(elementByLabel('Button component unmounted')).toBeVisible();
42
+  });
43
+
44
+  it('change button props without rendering all buttons', async () => {
45
+    await elementById(TestIDs.CHANGE_BUTTON_PROPS).tap();
46
+    await expect(elementByLabel('Three')).toBeVisible();
47
+  });
48
+});

+ 0
- 31
e2e/Options.test.js 파일 보기

27
     await expect(elementById(TestIDs.TOP_BAR)).toBeVisible();
27
     await expect(elementById(TestIDs.TOP_BAR)).toBeVisible();
28
   });
28
   });
29
 
29
 
30
-  it('sets right buttons', async () => {
31
-    await expect(elementById(TestIDs.BUTTON_ONE)).toBeVisible();
32
-    await expect(elementById(TestIDs.ROUND_BUTTON)).toBeVisible();
33
-  });
34
-
35
-  it('set left buttons', async () => {
36
-    await expect(elementById(TestIDs.LEFT_BUTTON)).toBeVisible();
37
-  });
38
-
39
-  it('pass props to custom button component', async () => {
40
-    await expect(elementByLabel('Two')).toExist();
41
-  });
42
-
43
-  it('pass props to custom button component should exist after push pop', async () => {
44
-    await expect(elementByLabel('Two')).toExist();
45
-    await elementById(TestIDs.PUSH_BTN).tap();
46
-    await elementById(TestIDs.POP_BTN).tap();
47
-    await expect(elementByLabel('Two')).toExist();
48
-  });
49
-
50
-  it('custom button is clickable', async () => {
51
-    await elementByLabel('Two').tap();
52
-    await expect(elementByLabel('Thanks for that :)')).toExist();
53
-  });
54
-
55
   it('default options should apply to all screens in stack', async () => {
30
   it('default options should apply to all screens in stack', async () => {
56
     await elementById(TestIDs.HIDE_TOPBAR_DEFAULT_OPTIONS).tap();
31
     await elementById(TestIDs.HIDE_TOPBAR_DEFAULT_OPTIONS).tap();
57
     await expect(elementById(TestIDs.TOP_BAR)).toBeVisible();
32
     await expect(elementById(TestIDs.TOP_BAR)).toBeVisible();
88
     await expect(elementByLabel('Styling Options')).toBeVisible();
63
     await expect(elementByLabel('Styling Options')).toBeVisible();
89
   });
64
   });
90
 
65
 
91
-  it(':ios: Reseting buttons should unmount button react view', async () => {
92
-    await elementById(TestIDs.SHOW_LIFECYCLE_BTN).tap();
93
-    await elementById(TestIDs.RESET_BUTTONS).tap();
94
-    await expect(elementByLabel('Button component unmounted')).toBeVisible();
95
-  });
96
-
97
   xit('hides topBar onScroll down and shows it on scroll up', async () => {
66
   xit('hides topBar onScroll down and shows it on scroll up', async () => {
98
     await elementById(TestIDs.PUSH_OPTIONS_BUTTON).tap();
67
     await elementById(TestIDs.PUSH_OPTIONS_BUTTON).tap();
99
     await elementById(TestIDs.SCROLLVIEW_SCREEN_BUTTON).tap();
68
     await elementById(TestIDs.SCROLLVIEW_SCREEN_BUTTON).tap();

+ 2
- 2
lib/src/commands/Commands.ts 파일 보기

55
 
55
 
56
   public mergeOptions(componentId: string, options: Options) {
56
   public mergeOptions(componentId: string, options: Options) {
57
     const input = _.cloneDeep(options);
57
     const input = _.cloneDeep(options);
58
-    this.optionsProcessor.processOptions(input);
58
+    this.optionsProcessor.processOptions(input, componentId);
59
 
59
 
60
     this.nativeCommandsSender.mergeOptions(componentId, input);
60
     this.nativeCommandsSender.mergeOptions(componentId, input);
61
     this.commandsObserver.notify('mergeOptions', { componentId, options });
61
     this.commandsObserver.notify('mergeOptions', { componentId, options });
64
   public showModal(layout: Layout) {
64
   public showModal(layout: Layout) {
65
     const layoutCloned = _.cloneDeep(layout);
65
     const layoutCloned = _.cloneDeep(layout);
66
     const layoutNode = this.layoutTreeParser.parse(layoutCloned);
66
     const layoutNode = this.layoutTreeParser.parse(layoutCloned);
67
-    
67
+
68
     const commandId = this.uniqueIdProvider.generate('showModal');
68
     const commandId = this.uniqueIdProvider.generate('showModal');
69
     this.commandsObserver.notify('showModal', { commandId, layout: layoutNode });
69
     this.commandsObserver.notify('showModal', { commandId, layout: layoutNode });
70
     this.layoutTreeCrawler.crawl(layoutNode);
70
     this.layoutTreeCrawler.crawl(layoutNode);

+ 10
- 0
lib/src/commands/OptionsProcessor.test.ts 파일 보기

135
     expect(options.topBar.title.component.passProps).toBeUndefined();
135
     expect(options.topBar.title.component.passProps).toBeUndefined();
136
     expect(options.topBar.background.component.passProps).toBeUndefined();
136
     expect(options.topBar.background.component.passProps).toBeUndefined();
137
   });
137
   });
138
+
139
+  it('calls store when component has passProps component id and values', () => {
140
+    const props = { prop: 'updated prop' };
141
+    const options = { passProps: props };
142
+
143
+    uut.processOptions(options, 'component1');
144
+
145
+    verify(mockedStore.setPropsForId('component1', props)).called();
146
+    expect(options.passProps).toBeUndefined();
147
+  });
138
 });
148
 });

+ 12
- 3
lib/src/commands/OptionsProcessor.ts 파일 보기

14
     private assetService: AssetService,
14
     private assetService: AssetService,
15
   ) {}
15
   ) {}
16
 
16
 
17
-  public processOptions(options: Options) {
18
-    this.processObject(options);
17
+  public processOptions(options: Options, componentId?: string) {
18
+    this.processObject(options, componentId);
19
   }
19
   }
20
 
20
 
21
-  private processObject(objectToProcess: object) {
21
+  private processObject(objectToProcess: object, componentId?: string) {
22
     _.forEach(objectToProcess, (value, key) => {
22
     _.forEach(objectToProcess, (value, key) => {
23
       this.processColor(key, value, objectToProcess);
23
       this.processColor(key, value, objectToProcess);
24
+
24
       if (!value) {
25
       if (!value) {
25
         return;
26
         return;
26
       }
27
       }
27
 
28
 
29
+      this.processProps(key, value, objectToProcess, componentId);
28
       this.processComponent(key, value, objectToProcess);
30
       this.processComponent(key, value, objectToProcess);
29
       this.processImage(key, value, objectToProcess);
31
       this.processImage(key, value, objectToProcess);
30
       this.processButtonsPassProps(key, value);
32
       this.processButtonsPassProps(key, value);
72
       options[key].passProps = undefined;
74
       options[key].passProps = undefined;
73
     }
75
     }
74
   }
76
   }
77
+
78
+  private processProps(key: string, value: any, options: Record<string, any>, componentId?: string) {
79
+    if (key === 'passProps' && componentId && value) {
80
+      this.store.setPropsForId(componentId, value);
81
+      options[key] = undefined;
82
+    }
83
+  }
75
 }
84
 }

+ 15
- 4
lib/src/components/ComponentWrapper.test.tsx 파일 보기

96
 
96
 
97
   it('updates props from store into inner component', () => {
97
   it('updates props from store into inner component', () => {
98
     const NavigationComponent = uut.wrap(componentName, () => MyComponent, store, componentEventsObserver);
98
     const NavigationComponent = uut.wrap(componentName, () => MyComponent, store, componentEventsObserver);
99
-    const tree = renderer.create(<TestParent ChildClass={NavigationComponent} />);
99
+    renderer.create(<TestParent ChildClass={NavigationComponent} />);
100
+    expect(myComponentProps.myProp).toEqual(undefined);
100
     store.setPropsForId('component1', { myProp: 'hello' });
101
     store.setPropsForId('component1', { myProp: 'hello' });
102
+    expect(myComponentProps.myProp).toEqual('hello');
103
+  });
104
+
105
+  it('updates props from state into inner component', () => {
106
+    const NavigationComponent = uut.wrap(componentName, () => MyComponent, store, componentEventsObserver);
107
+    const tree = renderer.create(<TestParent ChildClass={NavigationComponent} />);
101
     expect(myComponentProps.foo).toEqual(undefined);
108
     expect(myComponentProps.foo).toEqual(undefined);
102
-    expect(myComponentProps.myProp).toEqual(undefined);
103
     (tree.getInstance() as any).setState({ propsFromState: { foo: 'yo' } });
109
     (tree.getInstance() as any).setState({ propsFromState: { foo: 'yo' } });
104
     expect(myComponentProps.foo).toEqual('yo');
110
     expect(myComponentProps.foo).toEqual('yo');
105
-    expect(myComponentProps.myProp).toEqual('hello');
106
   });
111
   });
107
 
112
 
108
   it('protects id from change', () => {
113
   it('protects id from change', () => {
157
     expect(tree.root.findByType(MyComponent).props).toEqual({componentId: 'component123'});
162
     expect(tree.root.findByType(MyComponent).props).toEqual({componentId: 'component123'});
158
   });
163
   });
159
 
164
 
165
+  it('sets component instance in store when constructed', () => {
166
+    const NavigationComponent = uut.wrap(componentName, () => MyComponent, store, componentEventsObserver);
167
+    renderer.create(<NavigationComponent componentId={'component1'} />);
168
+    expect(store.getComponentInstance('component1')).toBeTruthy();
169
+  });
170
+
160
   describe(`register with redux store`, () => {
171
   describe(`register with redux store`, () => {
161
     class MyReduxComp extends React.Component<any> {
172
     class MyReduxComp extends React.Component<any> {
162
       static options() {
173
       static options() {
179
     const ConnectedComp = require('react-redux').connect(mapStateToProps)(MyReduxComp);
190
     const ConnectedComp = require('react-redux').connect(mapStateToProps)(MyReduxComp);
180
     const ReduxProvider = require('react-redux').Provider;
191
     const ReduxProvider = require('react-redux').Provider;
181
     const initialState: RootState = { txt: 'it just works' };
192
     const initialState: RootState = { txt: 'it just works' };
182
-    const reduxStore = require('redux').createStore((state = initialState) => state);
193
+    const reduxStore = require('redux').createStore((state: RootState = initialState) => state);
183
 
194
 
184
     it(`wraps the component with a react-redux provider with passed store`, () => {
195
     it(`wraps the component with a react-redux provider with passed store`, () => {
185
       const NavigationComponent = uut.wrap(componentName, () => ConnectedComp, store, componentEventsObserver, undefined, ReduxProvider, reduxStore);
196
       const NavigationComponent = uut.wrap(componentName, () => ConnectedComp, store, componentEventsObserver, undefined, ReduxProvider, reduxStore);

+ 10
- 1
lib/src/components/ComponentWrapper.tsx 파일 보기

10
 interface HocState { componentId: string; allProps: {}; }
10
 interface HocState { componentId: string; allProps: {}; }
11
 interface HocProps { componentId: string; }
11
 interface HocProps { componentId: string; }
12
 
12
 
13
+export interface IWrappedComponent extends React.Component {
14
+  setProps(newProps: Record<string, any>): void;
15
+}
16
+
13
 export class ComponentWrapper {
17
 export class ComponentWrapper {
14
   wrap(
18
   wrap(
15
     componentName: string | number,
19
     componentName: string | number,
35
           componentId: props.componentId,
39
           componentId: props.componentId,
36
           allProps: {}
40
           allProps: {}
37
         };
41
         };
42
+        store.setComponentInstance(props.componentId, this);
43
+      }
44
+
45
+      public setProps(newProps: any) {
46
+        this.setState({allProps: newProps});
38
       }
47
       }
39
 
48
 
40
       componentWillUnmount() {
49
       componentWillUnmount() {
41
-        store.cleanId(this.state.componentId);
50
+        store.clearComponent(this.state.componentId);
42
         componentEventsObserver.unmounted(this.state.componentId);
51
         componentEventsObserver.unmounted(this.state.componentId);
43
       }
52
       }
44
 
53
 

+ 27
- 3
lib/src/components/Store.test.ts 파일 보기

1
 import * as React from 'react';
1
 import * as React from 'react';
2
 import { Store } from './Store';
2
 import { Store } from './Store';
3
+import { IWrappedComponent } from './ComponentWrapper';
3
 
4
 
4
 describe('Store', () => {
5
 describe('Store', () => {
5
   let uut: Store;
6
   let uut: Store;
28
     expect(uut.getComponentClassForName('example.mycomponent')).toEqual(MyWrappedComponent);
29
     expect(uut.getComponentClassForName('example.mycomponent')).toEqual(MyWrappedComponent);
29
   });
30
   });
30
 
31
 
31
-  it('clean by component id', () => {
32
+  it('clear props by component id when clear component', () => {
32
     uut.setPropsForId('refUniqueId', { foo: 'bar' });
33
     uut.setPropsForId('refUniqueId', { foo: 'bar' });
34
+    uut.clearComponent('refUniqueId');
35
+    expect(uut.getPropsForId('refUniqueId')).toEqual({});
36
+  });
33
 
37
 
34
-    uut.cleanId('refUniqueId');
38
+  it('clear instance by component id when clear component', () => {
39
+    uut.setComponentInstance('refUniqueId', ({} as IWrappedComponent));
40
+    uut.clearComponent('refUniqueId');
41
+    expect(uut.getComponentInstance('refUniqueId')).toEqual(undefined);
42
+  });
35
 
43
 
36
-    expect(uut.getPropsForId('refUniqueId')).toEqual({});
44
+  it('holds component instance by id', () => {
45
+    uut.setComponentInstance('component1', ({} as IWrappedComponent));
46
+    expect(uut.getComponentInstance('component1')).toEqual({});
47
+  });
48
+
49
+  it('calls component setProps when set props by id', () => {
50
+    const instance: any = {setProps: jest.fn()};
51
+    const props = { foo: 'bar' };
52
+
53
+    uut.setComponentInstance('component1', instance);
54
+    uut.setPropsForId('component1', props);
55
+
56
+    expect(instance.setProps).toHaveBeenCalledWith(props);
57
+  });
58
+
59
+  it('not throw exeption when set props by id component not found', () => {
60
+    expect(() => uut.setPropsForId('component1', { foo: 'bar' })).not.toThrow();
37
   });
61
   });
38
 });
62
 });

+ 17
- 1
lib/src/components/Store.ts 파일 보기

1
 import { ComponentProvider } from 'react-native';
1
 import { ComponentProvider } from 'react-native';
2
+import { IWrappedComponent } from './ComponentWrapper';
2
 
3
 
3
 export class Store {
4
 export class Store {
4
   private componentsByName: Record<string, ComponentProvider> = {};
5
   private componentsByName: Record<string, ComponentProvider> = {};
5
   private propsById: Record<string, any> = {};
6
   private propsById: Record<string, any> = {};
7
+  private componentsInstancesById: Record<string, IWrappedComponent> = {};
6
 
8
 
7
   setPropsForId(componentId: string, props: any) {
9
   setPropsForId(componentId: string, props: any) {
8
     this.propsById[componentId] = props;
10
     this.propsById[componentId] = props;
11
+    const component = this.componentsInstancesById[componentId];
12
+
13
+    if (component) {
14
+      this.componentsInstancesById[componentId].setProps(props);
15
+    }
9
   }
16
   }
10
 
17
 
11
   getPropsForId(componentId: string) {
18
   getPropsForId(componentId: string) {
12
     return this.propsById[componentId] || {};
19
     return this.propsById[componentId] || {};
13
   }
20
   }
14
 
21
 
15
-  cleanId(componentId: string) {
22
+  clearComponent(componentId: string) {
16
     delete this.propsById[componentId];
23
     delete this.propsById[componentId];
24
+    delete this.componentsInstancesById[componentId];
17
   }
25
   }
18
 
26
 
19
   setComponentClassForName(componentName: string | number, ComponentClass: ComponentProvider) {
27
   setComponentClassForName(componentName: string | number, ComponentClass: ComponentProvider) {
23
   getComponentClassForName(componentName: string | number): ComponentProvider | undefined {
31
   getComponentClassForName(componentName: string | number): ComponentProvider | undefined {
24
     return this.componentsByName[componentName.toString()];
32
     return this.componentsByName[componentName.toString()];
25
   }
33
   }
34
+
35
+  setComponentInstance(id: string, component: IWrappedComponent): void {
36
+    this.componentsInstancesById[id] = component;
37
+  }
38
+
39
+  getComponentInstance(id: string): IWrappedComponent {
40
+    return this.componentsInstancesById[id];
41
+  }
26
 }
42
 }

+ 8
- 4
lib/src/interfaces/Options.ts 파일 보기

536
 
536
 
537
 export interface DotIndicatorOptions {
537
 export interface DotIndicatorOptions {
538
     // default red
538
     // default red
539
-    color?: Color,
539
+    color?: Color;
540
     // default 6
540
     // default 6
541
-    size?: number,
541
+    size?: number;
542
     // default false
542
     // default false
543
-    visible?: boolean,
543
+    visible?: boolean;
544
 }
544
 }
545
 
545
 
546
 export interface OptionsBottomTab {
546
 export interface OptionsBottomTab {
547
-    dotIndicator?: DotIndicatorOptions,
547
+    dotIndicator?: DotIndicatorOptions;
548
 
548
 
549
   /**
549
   /**
550
    * Set the text to display below the icon
550
    * Set the text to display below the icon
1019
    * @default false
1019
    * @default false
1020
    */
1020
    */
1021
   blurOnUnmount?: boolean;
1021
   blurOnUnmount?: boolean;
1022
+  /**
1023
+   * Props to pass to a component
1024
+   */
1025
+  passProps?: Record<string, any>;
1022
 }
1026
 }

+ 1
- 0
package.json 파일 보기

20
   "typings": "lib/dist/index.d.ts",
20
   "typings": "lib/dist/index.d.ts",
21
   "scripts": {
21
   "scripts": {
22
     "build": "rm -rf ./lib/dist && tsc",
22
     "build": "rm -rf ./lib/dist && tsc",
23
+    "watch": "rm -rf ./lib/dist && tsc --watch",
23
     "xcode": "open playground/ios/playground.xcodeproj",
24
     "xcode": "open playground/ios/playground.xcodeproj",
24
     "install-android": "node ./scripts/install-android",
25
     "install-android": "node ./scripts/install-android",
25
     "uninstall-android": "cd playground/android && ./gradlew uninstallAll",
26
     "uninstall-android": "cd playground/android && ./gradlew uninstallAll",

+ 105
- 0
playground/src/screens/ButtonsScreen.js 파일 보기

1
+const React = require('react');
2
+const {Component} = require('react');
3
+const Root = require('../components/Root');
4
+const Button = require('../components/Button')
5
+const Navigation = require('../services/Navigation');
6
+const Screens = require('./Screens');
7
+const Colors = require('../commons/Colors');
8
+const {
9
+  PUSH_BTN,
10
+  TOP_BAR,
11
+  ROUND_BUTTON,
12
+  BUTTON_ONE,
13
+  LEFT_BUTTON,
14
+  SHOW_LIFECYCLE_BTN,
15
+  RESET_BUTTONS,
16
+  CHANGE_BUTTON_PROPS
17
+} = require('../testIDs');
18
+
19
+class Options extends Component {
20
+  static options() {
21
+    return {
22
+      topBar: {
23
+        visible: true,
24
+        testID: TOP_BAR,
25
+        title: {
26
+          text: 'Styling Options'
27
+        },
28
+        rightButtons: [
29
+          {
30
+            id: 'ONE',
31
+            testID: BUTTON_ONE,
32
+            text: 'One',
33
+            color: Colors.primary
34
+          },
35
+          {
36
+            id: 'ROUND',
37
+            testID: ROUND_BUTTON,
38
+            component: {
39
+              id: 'ROUND_COMPONENT',
40
+              name: Screens.RoundButton,
41
+              passProps: {
42
+                title: 'Two'
43
+              }
44
+            }
45
+          }
46
+        ],
47
+        leftButtons: [
48
+          {
49
+            id: 'LEFT',
50
+            testID: LEFT_BUTTON,
51
+            icon: require('../../img/clear.png'),
52
+            color: Colors.primary
53
+          }
54
+        ]
55
+      }
56
+    };
57
+  }
58
+
59
+  render() {
60
+    return (
61
+      <Root componentId={this.props.componentId}>
62
+        <Button label='Push' testID={PUSH_BTN} onPress={this.push} />
63
+        <Button label='Show Lifecycle button' testID={SHOW_LIFECYCLE_BTN} onPress={this.showLifecycleButton} />
64
+        <Button label='Remove all buttons' testID={RESET_BUTTONS} onPress={this.resetButtons} />
65
+        <Button label='Change Button Props'  testID={CHANGE_BUTTON_PROPS} onPress={this.changeButtonProps} />
66
+      </Root>
67
+    );
68
+  }
69
+
70
+  push = () => Navigation.push(this, Screens.Pushed);
71
+
72
+  showLifecycleButton = () => Navigation.mergeOptions(this, {
73
+    topBar: {
74
+      rightButtons: [
75
+        {
76
+          id: 'ROUND',
77
+          testID: ROUND_BUTTON,
78
+          component: {
79
+            name: Screens.LifecycleButton,
80
+            passProps: {
81
+              title: 'Two'
82
+            }
83
+          }
84
+        }
85
+      ]
86
+    }
87
+  });
88
+
89
+  resetButtons = () => Navigation.mergeOptions(this, {
90
+    topBar: {
91
+      rightButtons: [],
92
+      leftButtons: []
93
+    }
94
+  });
95
+
96
+  changeButtonProps = () => {
97
+    Navigation.mergeOptions('ROUND_COMPONENT', {
98
+      passProps: {
99
+        title: 'Three'
100
+      }
101
+    });
102
+  }
103
+}
104
+
105
+module.exports = Options;

+ 5
- 59
playground/src/screens/OptionsScreen.js 파일 보기

4
 const Button = require('../components/Button')
4
 const Button = require('../components/Button')
5
 const Navigation = require('../services/Navigation');
5
 const Navigation = require('../services/Navigation');
6
 const Screens = require('./Screens');
6
 const Screens = require('./Screens');
7
-const Colors = require('../commons/Colors');
8
 const {
7
 const {
9
   CHANGE_TITLE_BTN,
8
   CHANGE_TITLE_BTN,
10
   HIDE_TOP_BAR_BTN,
9
   HIDE_TOP_BAR_BTN,
11
   SHOW_TOP_BAR_BTN,
10
   SHOW_TOP_BAR_BTN,
12
   TOP_BAR,
11
   TOP_BAR,
13
-  ROUND_BUTTON,
14
-  BUTTON_ONE,
15
-  LEFT_BUTTON,
16
   PUSH_BTN,
12
   PUSH_BTN,
17
   HIDE_TOPBAR_DEFAULT_OPTIONS,
13
   HIDE_TOPBAR_DEFAULT_OPTIONS,
18
   SHOW_YELLOW_BOX_BTN,
14
   SHOW_YELLOW_BOX_BTN,
19
   SET_REACT_TITLE_VIEW,
15
   SET_REACT_TITLE_VIEW,
20
-  RESET_BUTTONS,
21
-  SHOW_LIFECYCLE_BTN
16
+  GOTO_BUTTONS_SCREEN
22
 } = require('../testIDs');
17
 } = require('../testIDs');
23
 
18
 
24
 class Options extends Component {
19
 class Options extends Component {
29
         testID: TOP_BAR,
24
         testID: TOP_BAR,
30
         title: {
25
         title: {
31
           text: 'Styling Options'
26
           text: 'Styling Options'
32
-        },
33
-        rightButtons: [
34
-          {
35
-            id: 'ONE',
36
-            testID: BUTTON_ONE,
37
-            text: 'One',
38
-            color: Colors.primary
39
-          },
40
-          {
41
-            id: 'ROUND',
42
-            testID: ROUND_BUTTON,
43
-            component: {
44
-              name: Screens.RoundButton,
45
-              passProps: {
46
-                title: 'Two'
47
-              }
48
-            }
49
-          }
50
-        ],
51
-        leftButtons: [
52
-          {
53
-            id: 'LEFT',
54
-            testID: LEFT_BUTTON,
55
-            icon: require('../../img/clear.png'),
56
-            color: Colors.primary
57
-          }
58
-        ]
27
+        }
59
       }
28
       }
60
     };
29
     };
61
   }
30
   }
71
         <Button label='Set React Title View' testID={SET_REACT_TITLE_VIEW} onPress={this.setReactTitleView} />
40
         <Button label='Set React Title View' testID={SET_REACT_TITLE_VIEW} onPress={this.setReactTitleView} />
72
         <Button label='Show Yellow Box' testID={SHOW_YELLOW_BOX_BTN} onPress={() => console.warn('Yellow Box')} />
41
         <Button label='Show Yellow Box' testID={SHOW_YELLOW_BOX_BTN} onPress={() => console.warn('Yellow Box')} />
73
         <Button label='StatusBar' onPress={this.statusBarScreen} />
42
         <Button label='StatusBar' onPress={this.statusBarScreen} />
74
-        <Button label='Show Lifecycle button' testID={SHOW_LIFECYCLE_BTN} onPress={this.showLifecycleButton} />
75
-        <Button label='Remove all buttons' testID={RESET_BUTTONS} onPress={this.resetButtons} />
43
+        <Button label='Buttons Screen' testID={GOTO_BUTTONS_SCREEN} onPress={this.goToButtonsScreen} />
76
       </Root>
44
       </Root>
77
     );
45
     );
78
   }
46
   }
79
 
47
 
80
-  showLifecycleButton = () => Navigation.mergeOptions(this, {
81
-    topBar: {
82
-      rightButtons: [
83
-        {
84
-          id: 'ROUND',
85
-          testID: ROUND_BUTTON,
86
-          component: {
87
-            name: Screens.LifecycleButton,
88
-            passProps: {
89
-              title: 'Two'
90
-            }
91
-          }
92
-        }
93
-      ]
94
-    }
95
-  });
96
-
97
-  resetButtons = () => Navigation.mergeOptions(this, {
98
-    topBar: {
99
-      rightButtons: [],
100
-      leftButtons: []
101
-    }
102
-  });
103
-
104
   changeTitle = () => Navigation.mergeOptions(this, {
48
   changeTitle = () => Navigation.mergeOptions(this, {
105
     topBar: {
49
     topBar: {
106
       title: {
50
       title: {
149
   });
93
   });
150
 
94
 
151
   statusBarScreen = () => Navigation.showModal(Screens.StatusBar);
95
   statusBarScreen = () => Navigation.showModal(Screens.StatusBar);
96
+
97
+  goToButtonsScreen = () => Navigation.push(this, Screens.Buttons);
152
 }
98
 }
153
 
99
 
154
 module.exports = Options;
100
 module.exports = Options;

+ 1
- 0
playground/src/screens/Screens.js 파일 보기

11
   Pushed: 'Pushed',
11
   Pushed: 'Pushed',
12
   Layouts: 'Layouts',
12
   Layouts: 'Layouts',
13
   Options: 'Options',
13
   Options: 'Options',
14
+  Buttons: 'Buttons',
14
   Stack: 'Stack',
15
   Stack: 'Stack',
15
   Modal: 'Modal',
16
   Modal: 'Modal',
16
   FullScreenModal: 'FullScreenModal',
17
   FullScreenModal: 'FullScreenModal',

+ 1
- 1
playground/src/screens/index.js 파일 보기

23
   Navigation.registerComponent(Screens.FullScreenModal, () => require('./FullScreenModalScreen'))
23
   Navigation.registerComponent(Screens.FullScreenModal, () => require('./FullScreenModalScreen'))
24
   Navigation.registerComponent(Screens.Navigation, () => require('./NavigationScreen'));
24
   Navigation.registerComponent(Screens.Navigation, () => require('./NavigationScreen'));
25
   Navigation.registerComponent(Screens.Options, () => require('./OptionsScreen'));
25
   Navigation.registerComponent(Screens.Options, () => require('./OptionsScreen'));
26
+  Navigation.registerComponent(Screens.Buttons, () => require('./ButtonsScreen'));
26
   Navigation.registerComponent(Screens.Orientation, () => require('./OrientationScreen'));
27
   Navigation.registerComponent(Screens.Orientation, () => require('./OrientationScreen'));
27
   Navigation.registerComponent(Screens.OrientationDetect, () => require('./OrientationDetectScreen'));
28
   Navigation.registerComponent(Screens.OrientationDetect, () => require('./OrientationDetectScreen'));
28
   Navigation.registerComponent(Screens.Overlay, () => require('./OverlayScreen'));
29
   Navigation.registerComponent(Screens.Overlay, () => require('./OverlayScreen'));
29
   Navigation.registerComponent(Screens.OverlayAlert, () => require('./OverlayAlert'));
30
   Navigation.registerComponent(Screens.OverlayAlert, () => require('./OverlayAlert'));
30
   Navigation.registerComponent(Screens.Pushed, () => require('./PushedScreen'));
31
   Navigation.registerComponent(Screens.Pushed, () => require('./PushedScreen'));
31
   Navigation.registerComponent(Screens.ScrollViewOverlay, () => require('./ScrollViewOverlay'));
32
   Navigation.registerComponent(Screens.ScrollViewOverlay, () => require('./ScrollViewOverlay'));
32
-  Navigation.registerComponent(Screens.RoundButton, () => require('./RoundedButton'));
33
   Navigation.registerComponent(Screens.LifecycleButton, () => require('./LifecycleButton'));
33
   Navigation.registerComponent(Screens.LifecycleButton, () => require('./LifecycleButton'));
34
   Navigation.registerComponent(Screens.ReactTitleView, () => require('./CustomTopBar'));
34
   Navigation.registerComponent(Screens.ReactTitleView, () => require('./CustomTopBar'));
35
   Navigation.registerComponent(Screens.RoundButton, () => require('./RoundedButton'));
35
   Navigation.registerComponent(Screens.RoundButton, () => require('./RoundedButton'));

+ 3
- 0
playground/src/testIDs.js 파일 보기

7
   LAYOUTS_TAB: 'LAYOUTS_TAB',
7
   LAYOUTS_TAB: 'LAYOUTS_TAB',
8
   NAVIGATION_TAB: 'NAVIGATION_TAB',
8
   NAVIGATION_TAB: 'NAVIGATION_TAB',
9
   OPTIONS_TAB: 'OPTIONS_TAB',
9
   OPTIONS_TAB: 'OPTIONS_TAB',
10
+  BUTTONS_TAB: 'BUTTONS_TAB',
10
   SIDE_MENU_INSIDE_BOTTOM_TABS_BTN: 'SIDE_MENU_INSIDE_BOTTOM_TABS',
11
   SIDE_MENU_INSIDE_BOTTOM_TABS_BTN: 'SIDE_MENU_INSIDE_BOTTOM_TABS',
11
   OVERLAY_BTN: 'OVERLAY_BTN',
12
   OVERLAY_BTN: 'OVERLAY_BTN',
12
   SIDE_MENU_BTN: 'SIDE_MENU_BTN',
13
   SIDE_MENU_BTN: 'SIDE_MENU_BTN',
130
   SET_ROOT:'SET_ROOT',
131
   SET_ROOT:'SET_ROOT',
131
   RESET_BUTTONS: 'RESET_BUTTONS',
132
   RESET_BUTTONS: 'RESET_BUTTONS',
132
   SHOW_LIFECYCLE_BTN: 'SHOW_LIFECYCLE_BTN',
133
   SHOW_LIFECYCLE_BTN: 'SHOW_LIFECYCLE_BTN',
134
+  CHANGE_BUTTON_PROPS: 'CHANGE_BUTTON_PROPS',
135
+  GOTO_BUTTONS_SCREEN: 'GOTO_BUTTONS_SCREEN',
133
 
136
 
134
   // Elements
137
   // Elements
135
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,
138
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,