mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-22 19:58:25 +08:00
@@ -4,8 +4,9 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import DimensionsChange from './examples/DimensionsChange';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { AppText, Code, DocItem, TextList } from '../../ui-explorer';
|
||||
import React from 'react';
|
||||
|
||||
const sections = [
|
||||
@@ -19,6 +20,34 @@ const sections = [
|
||||
example={{
|
||||
code: "const { height, width } = Dimensions.get('window')"
|
||||
}}
|
||||
/>,
|
||||
<DocItem
|
||||
name="static addEventLitener"
|
||||
typeInfo="(type: string, handler: function) => void"
|
||||
description={[
|
||||
<AppText>Add an event handler. Supported events:</AppText>,
|
||||
|
||||
<TextList
|
||||
items={[
|
||||
<AppText>
|
||||
<Code>change</Code>: Fires when a property within the <Code>Dimensions</Code> object
|
||||
changes. The argument to the event handler is an object
|
||||
with <Code>window</Code> and <Code>screen</Code> properties whose values are the
|
||||
same as the return values of <Code>Dimensions.get('window')</Code> and{' '}
|
||||
<Code>Dimensions.get('screen')</Code>,
|
||||
respectively.
|
||||
</AppText>
|
||||
]}
|
||||
/>
|
||||
]}
|
||||
example={{
|
||||
render: () => <DimensionsChange />
|
||||
}}
|
||||
/>,
|
||||
<DocItem
|
||||
name="static removeEventLitener"
|
||||
typeInfo="(type: string, handler: function) => void"
|
||||
description="Remove an event handler."
|
||||
/>
|
||||
]
|
||||
}
|
||||
@@ -29,5 +58,6 @@ storiesOf('APIs', module).add('Dimensions', () =>
|
||||
description="Note: dimensions may change (e.g., due to device rotation) so any rendering logic or styles that depend on these constants should try to call this function on every render, rather than caching the value."
|
||||
sections={sections}
|
||||
title="Dimensions"
|
||||
url="apis/Dimensions"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Button, Dimensions, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export default class ChangeEventExample extends Component {
|
||||
state = {
|
||||
listened: false,
|
||||
logs: []
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
Dimensions.removeEventListener('change', this._handleChange);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { logs, listened } = this.state;
|
||||
const buttonTitle = listened ? 'Remove listener' : 'Add listener';
|
||||
return (
|
||||
<View>
|
||||
<Button onPress={this.toggle} title={buttonTitle} />
|
||||
<ScrollView style={styles.logs}>
|
||||
{logs.map((log, i) => <Text key={i} style={styles.log}>{log}</Text>)}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
const { listened } = this.state;
|
||||
if (listened) {
|
||||
Dimensions.removeEventListener('change', this._handleChange);
|
||||
this._log('Removed listener');
|
||||
} else {
|
||||
Dimensions.addEventListener('change', this._handleChange);
|
||||
this._log('Added listener');
|
||||
}
|
||||
this.setState(() => ({ listened: !listened }));
|
||||
};
|
||||
|
||||
_handleChange = ({ window, screen }) => {
|
||||
window = JSON.stringify(window, null, 2);
|
||||
screen = JSON.stringify(screen, null, 2);
|
||||
this._log(`Changed\nwindow = ${window}\nscreen = ${screen}`);
|
||||
};
|
||||
|
||||
_log = msg => {
|
||||
this.setState(state => ({
|
||||
logs: [`${new Date().toTimeString()} - ${msg}`, ...state.logs]
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
logs: {
|
||||
maxHeight: 256
|
||||
},
|
||||
log: {
|
||||
fontFamily: 'monospace, monospace',
|
||||
marginTop: 8,
|
||||
marginBottom: 8
|
||||
}
|
||||
});
|
||||
@@ -26,7 +26,7 @@ const styles = StyleSheet.create({
|
||||
bullet: {
|
||||
position: 'absolute',
|
||||
left: 6,
|
||||
top: '50%',
|
||||
top: '.65625rem',
|
||||
marginTop: -2,
|
||||
height: 4,
|
||||
width: 4,
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
|
||||
import Dimensions from '..';
|
||||
|
||||
describe('apis/Dimensions', () => {
|
||||
test.skip('NO TEST COVERAGE', () => {});
|
||||
test('addEventListener', () => {
|
||||
const handler = jest.fn();
|
||||
Dimensions.addEventListener('change', handler);
|
||||
Dimensions.set();
|
||||
expect(handler).toHaveBeenCalledTimes(1);
|
||||
expect(handler).toHaveBeenLastCalledWith({
|
||||
window: Dimensions.get('window'),
|
||||
screen: Dimensions.get('screen')
|
||||
});
|
||||
});
|
||||
|
||||
test('removeEventListener', () => {
|
||||
const handler = jest.fn();
|
||||
Dimensions.removeEventListener('change', handler);
|
||||
Dimensions.set();
|
||||
expect(handler).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,6 +27,7 @@ const win = canUseDOM
|
||||
};
|
||||
|
||||
const dimensions = {};
|
||||
const listeners = {};
|
||||
|
||||
export default class Dimensions {
|
||||
static get(dimension: string): Object {
|
||||
@@ -48,6 +49,21 @@ export default class Dimensions {
|
||||
scale: win.devicePixelRatio || 1,
|
||||
width: win.screen.width
|
||||
};
|
||||
|
||||
if (Array.isArray(listeners['change'])) {
|
||||
listeners['change'].forEach(handler => handler(dimensions));
|
||||
}
|
||||
}
|
||||
|
||||
static addEventListener(type, handler): void {
|
||||
listeners[type] = listeners[type] || [];
|
||||
listeners[type].push(handler);
|
||||
}
|
||||
|
||||
static removeEventListener(type, handler): void {
|
||||
if (Array.isArray(listeners[type])) {
|
||||
listeners[type] = listeners[type].filter(_handler => _handler !== handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user