Skip to content

Commit 02e7a60

Browse files
committed
WIP: support landscape orientation and switching between orientations
1 parent 0710858 commit 02e7a60

File tree

3 files changed

+104
-73
lines changed

3 files changed

+104
-73
lines changed

lib/components/overlay.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from "react";
2+
import { Animated, StyleSheet, Text } from "react-native";
3+
4+
export const styles = StyleSheet.create( {
5+
overlay: {
6+
position: "absolute",
7+
top: 0,
8+
right: 0,
9+
bottom: 0,
10+
left: 0,
11+
backgroundColor: "#000"
12+
},
13+
14+
overlayInner: {
15+
top: 0,
16+
right: 0,
17+
height: "100%",
18+
width: "100%"
19+
}
20+
21+
} );
22+
23+
24+
export default props => {
25+
26+
const { opacity, onPress } = props;
27+
28+
return (
29+
<Animated.View
30+
style={ [
31+
styles.overlay,
32+
{
33+
opacity: opacity.interpolate( {
34+
inputRange: [ 0, 1 ],
35+
outputRange: [ 0, 0.4 ]
36+
} )
37+
}
38+
] }
39+
>
40+
<Text style={ styles.overlayInner } onPress={ onPress }/>
41+
</Animated.View>
42+
);
43+
44+
}

lib/power-action-sheet-styles.js

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,6 @@ const hairlineWidth = StyleSheet.hairlineWidth;
55

66
const base = {
77

8-
overlay: {
9-
position: "absolute",
10-
top: 0,
11-
right: 0,
12-
bottom: 0,
13-
left: 0,
14-
backgroundColor: "#000"
15-
},
16-
17-
overlayInner: {
18-
top: 0,
19-
right: 0,
20-
height: "100%",
21-
width: "100%"
22-
},
23-
24-
wrapper: {
25-
flex: 1,
26-
flexDirection: "row",
27-
backgroundColor: "transparent",
28-
},
29-
308
sheet: {
319
position: "absolute",
3210
display: "flex",

lib/power-action-sheet.js

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import createStyles from "./power-action-sheet-styles";
2+
import Overlay from "./components/overlay";
23
import CancelButton from "./components/cancel-button";
34

45
import getWindowHeight from "./window-height";
56

67
import React, { Component } from "react";
78
import { element, func, number, object, oneOfType, string } from "prop-types";
8-
import { Animated, LayoutAnimation, Modal, Platform, ScrollView, Text, View } from "react-native";
9+
import { Animated, Dimensions, LayoutAnimation, Modal, Platform, ScrollView, View } from "react-native";
910

1011

1112
const defaultOptions = {
12-
maxHeightRatio: 0.9,
13+
maxHeightRatio: .9,
1314
sheetView: () => null,
1415
onClose: () => {}
1516
};
@@ -49,9 +50,16 @@ class PowerActionSheet extends Component {
4950
visible: false,
5051
stage: Stage.closed,
5152
overlayOpacity: new Animated.Value( 0 ),
52-
styles: {}
53+
styles: null
5354
};
5455

56+
componentDidMount() {
57+
Dimensions.addEventListener( "change", this._onDimensionsChange );
58+
}
59+
60+
componentWillUnmount() {
61+
Dimensions.removeEventListener( "change", this._onDimensionsChange );
62+
}
5563

5664
open = async ( options = {} ) => {
5765
if ( this.state.stage !== Stage.closed )
@@ -78,7 +86,7 @@ class PowerActionSheet extends Component {
7886
duration: easeInEaseOut.duration,
7987
useNativeDriver: true
8088
} ).start( async () => {
81-
await this._promiseState( { stage: Stage.closed } );
89+
await this._promiseState( { stage: Stage.closed, styles: null } );
8290
await this._promiseState( { visible: false, result } );
8391
if ( Platform.OS === "android" )
8492
this._onDismiss();
@@ -121,21 +129,48 @@ class PowerActionSheet extends Component {
121129
async _promiseSheet( options ) {
122130
options = { ...pickDefaultOptions( this.props ), ...options };
123131

124-
const maxHeight = getWindowHeight() * options.maxHeightRatio;
125-
126132
return this._promiseState( {
127133
options,
128-
maxHeight,
129134
overflowing: false,
130135
visible: true,
131-
stage: Stage.opening,
136+
stage: Stage.opening
137+
} );
138+
}
139+
140+
_calcStyles() {
141+
const maxHeight = getWindowHeight() * this.state.options.maxHeightRatio;
142+
143+
return {
144+
maxHeight,
132145
styles: {
133146
...createStyles( this.props.styles ),
134147
buttonUnderlayColor: this.props.buttonUnderlayColor
135148
}
136-
} );
149+
};
137150
}
138151

152+
153+
_onDimensionsChange = () => {
154+
switch ( this.state.stage ) {
155+
case Stage.opened:
156+
case Stage.opening:
157+
this.setState( {
158+
stage: Stage.closed
159+
}, () => {
160+
this.setState( {
161+
...this._calcStyles(),
162+
stage: Stage.opening
163+
} );
164+
} );
165+
break;
166+
}
167+
};
168+
169+
_onShow = () => {
170+
return this.setState( this._calcStyles() );
171+
};
172+
173+
139174
_onLayout = event => {
140175
if ( this.state.stage !== Stage.opening )
141176
return;
@@ -154,70 +189,44 @@ class PowerActionSheet extends Component {
154189

155190

156191
render() {
157-
const { visible } = this.state;
192+
const { overlayOpacity, visible } = this.state;
158193

159194
return (
160195
<Modal
161196
visible={ visible }
162197
transparent={ true }
163198
animationType="none"
199+
supportedOrientations={ [ "portrait", "landscape" ] }
164200
onRequestClose={ this.cancel }
201+
onShow={ this._onShow }
165202
onDismiss={ this._onDismiss }
166203
>
167-
{ this._renderContent() }
204+
<Overlay opacity={ overlayOpacity } onPress={ this.cancel }/>
205+
{ this._renderSheet() }
168206
</Modal>
169207
)
170208
}
171209

172-
_renderContent() {
173-
const { stage, styles } = this.state;
174210

175-
if ( stage === Stage.closed )
176-
return null;
211+
_renderSheet() {
212+
const { maxHeight, height, overflowing, stage, styles, options } = this.state;
177213

178-
return (
179-
<View style={ styles.wrapper }>
180-
{ this._renderOverlay( styles ) }
181-
{ this._renderSheet( styles ) }
182-
</View>
183-
);
184-
}
185-
186-
_renderOverlay( styles ) {
187-
const { overlayOpacity } = this.state;
214+
if ( !styles || stage === Stage.closed )
215+
return null;
188216

189-
return (
190-
<Animated.View
191-
style={ [
192-
styles.overlay,
193-
{
194-
opacity: overlayOpacity.interpolate( {
195-
inputRange: [ 0, 1 ],
196-
outputRange: [ 0, 0.4 ]
197-
} )
198-
}
199-
] }
200-
>
201-
<Text style={ styles.overlayInner } onPress={ this.cancel }/>
202-
</Animated.View>
203-
);
204-
}
205217

218+
const calculating = stage === Stage.opening;
219+
const scrollEnabled = !calculating && overflowing;
206220

207-
_renderSheet( styles ) {
208-
const { maxHeight, height, overflowing, stage, options } = this.state;
209221

210-
const calculating = stage === Stage.opening;
222+
const sheetStyle = [ styles.sheet ];
211223

212-
const sheetStyle = [
213-
styles.sheet
214-
];
215224
switch ( stage ) {
216225
case Stage.opened:
217-
sheetStyle.push( { bottom: 0, height } );
226+
sheetStyle.push( { bottom: 0, maxHeight: height } );
218227
break;
219228
case Stage.closing:
220-
sheetStyle.push( { top: "100%", height } );
229+
sheetStyle.push( { top: "100%", maxHeight: height } );
221230
break;
222231
case Stage.opening:
223232
case Stage.closed:
@@ -226,9 +235,9 @@ class PowerActionSheet extends Component {
226235
}
227236

228237
const ScrollableContent = ( props ) => {
229-
const scrollEnabled = !calculating && overflowing;
230238
return (
231239
<ScrollView
240+
key="ScrollableContent"
232241
{ ...props }
233242
scrollEnabled={ scrollEnabled }
234243
showsHorizontalScrollIndicator={ scrollEnabled }
@@ -245,7 +254,7 @@ class PowerActionSheet extends Component {
245254
<Sheet
246255
styles={ styles }
247256
calculating={ calculating }
248-
overflowing={ overflowing }
257+
overflowing={ scrollEnabled }
249258
open={ this.open }
250259
close={ this.close }
251260
ScrollableContent={ ScrollableContent }

0 commit comments

Comments
 (0)