Permalink
Browse files

Fix and improve forwarding of measurement methods

- Add missing forwarding to ripple components required for forwarding on higher level components to actually work
- Reduce the forwarding boilerplate with a decorator util
  • Loading branch information...
dantman committed Nov 22, 2017
1 parent 2249228 commit 65ff5ac5caebf3336963da33b6dab52d53d88a8d
View
@@ -2,6 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet, View, Text} from 'react-native';
import withMaterialTheme from './styles/withMaterialTheme';
import {withMeasurementForwarding} from './util';
import * as typo from './styles/typo';
import shades from './styles/shades';
@@ -14,11 +15,6 @@ class Subheader extends PureComponent {
lines: 1,
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
materialTheme,
@@ -48,7 +44,7 @@ class Subheader extends PureComponent {
return (
<View
ref={this._setRef}
ref={this._setMeasureRef}
style={[
styles.container,
inset && styles.inset,
@@ -70,7 +66,7 @@ class Subheader extends PureComponent {
}
}
export default withMaterialTheme(Subheader);
export default withMaterialTheme(withMeasurementForwarding(Subheader));
const styles = StyleSheet.create({
container: {
View
@@ -3,7 +3,7 @@ import React, {PureComponent} from 'react';
import ActionList from './ActionList';
import {StyleSheet, Text} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, PRESS_HANDLERS, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, PRESS_HANDLERS, LAYOUT_PROPS} from '../util';
import CoreRipple from '../touchable/CoreRipple';
import * as typo from '../styles/typo';
import {
@@ -25,11 +25,6 @@ class ActionButton extends PureComponent {
borderless: false,
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
materialTheme,
@@ -93,7 +88,7 @@ class ActionButton extends PureComponent {
return (
<CoreRipple
ref={this._setRef}
ref={this._setMeasureRef}
pointerEvents='box-only'
accessibilityComponentType='button'
accessibilityTraits={disabled ? 'disabled' : 'button'}
@@ -113,7 +108,7 @@ class ActionButton extends PureComponent {
}
}
export default withMaterialTheme(ActionButton);
export default withMaterialTheme(withMeasurementForwarding(ActionButton));
const styles = StyleSheet.create({
root: {
View
@@ -2,7 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet, Text} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, PRESS_HANDLERS, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, PRESS_HANDLERS, LAYOUT_PROPS} from '../util';
import RectRipple from '../touchable/RectRipple';
import elevation from '../styles/elevation';
import * as typo from '../styles/typo';
@@ -22,11 +22,6 @@ class Button extends PureComponent {
disabled: false,
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
materialTheme,
@@ -86,7 +81,7 @@ class Button extends PureComponent {
return (
<RectRipple
ref={this._setRef}
ref={this._measureRef}
pointerEvents='box-only'
accessibilityComponentType='button'
accessibilityTraits={disabled ? 'disabled' : 'button'}
@@ -119,7 +114,7 @@ class Button extends PureComponent {
}
}
export default withMaterialTheme(Button);
export default withMaterialTheme(withMeasurementForwarding(Button));
const styles = StyleSheet.create({
root: {
View
@@ -2,7 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, PRESS_HANDLERS, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, PRESS_HANDLERS, LAYOUT_PROPS} from '../util';
import CircleHighlight from '../touchable/CircleHighlight';
import elevation from '../styles/elevation';
import {largePrimaryTextShade} from '../styles/contrast';
@@ -12,11 +12,6 @@ class FAB extends PureComponent {
disabled: false,
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
materialTheme,
@@ -54,7 +49,7 @@ class FAB extends PureComponent {
return (
// CircleHighlight is currently used insdead of CircleRipple due to ReactNative Android's overflow bug
<CircleHighlight
ref={this._setRef}
ref={this._setMeasureRef}
pointerEvents='box-only'
{...pressHandlers}
{...layoutProps}
@@ -76,7 +71,7 @@ class FAB extends PureComponent {
}
}
export default withMaterialTheme(FAB);
export default withMaterialTheme(withMeasurementForwarding(FAB));
const styles = StyleSheet.create({
base: {
View
@@ -2,7 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, LAYOUT_PROPS} from '../util';
import CircleHighlight from '../touchable/CircleHighlight';
import CoreCheckbox from './CoreCheckbox';
@@ -19,11 +19,6 @@ class Checkbox extends PureComponent {
this.props.onChangeChecked && this.props.onChangeChecked(!this.props.checked);
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
onPress, // eslint-disable-line no-unused-vars
@@ -54,7 +49,7 @@ class Checkbox extends PureComponent {
// @todo Use disabled to disable ripple/press
return (
<CircleHighlight
ref={this._setRef}
ref={this._setMeasureRef}
{...rippleProps}
{...layoutProps}
pointerEvents='box-only'
@@ -70,7 +65,7 @@ class Checkbox extends PureComponent {
}
}
export default withMaterialTheme(Checkbox);
export default withMaterialTheme(withMeasurementForwarding(Checkbox));
const styles = StyleSheet.create({
root: {
@@ -2,7 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet, Text} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, LAYOUT_PROPS} from '../util';
import RectRipple from '../touchable/RectRipple';
import CoreCheckbox from './CoreCheckbox';
import * as typo from '../styles/typo';
@@ -20,11 +20,6 @@ class LabeledCheckbox extends PureComponent {
this.props.onChangeChecked && this.props.onChangeChecked(!this.props.checked);
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
onPress, // eslint-disable-line no-unused-vars
@@ -47,7 +42,7 @@ class LabeledCheckbox extends PureComponent {
// @todo Use disabled to disable ripple/press
return (
<RectRipple
ref={this._setRef}
ref={this._setMeasureRef}
{...normalProps}
{...layoutProps}
pointerEvents='box-only'
@@ -76,7 +71,7 @@ class LabeledCheckbox extends PureComponent {
}
}
export default withMaterialTheme(LabeledCheckbox);
export default withMaterialTheme(withMeasurementForwarding(LabeledCheckbox));
const styles = StyleSheet.create({
root: {
View
@@ -2,7 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet, Text} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, LAYOUT_PROPS} from '../util';
import RectRipple from '../touchable/RectRipple';
import CoreRadio from './CoreRadio';
import * as typo from '../styles/typo';
@@ -20,11 +20,6 @@ class LabeledRadio extends PureComponent {
this.props.onChangeChecked && this.props.onChangeChecked(!this.props.checked);
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
onPress, // eslint-disable-line no-unused-vars
@@ -47,7 +42,7 @@ class LabeledRadio extends PureComponent {
// @todo Use disabled to disable ripple/press
return (
<RectRipple
ref={this._setRef}
ref={this._setMeasureRef}
{...normalProps}
{...layoutProps}
pointerEvents='box-only'
@@ -76,7 +71,7 @@ class LabeledRadio extends PureComponent {
}
}
export default withMaterialTheme(LabeledRadio);
export default withMaterialTheme(withMeasurementForwarding(LabeledRadio));
const styles = StyleSheet.create({
root: {
View
@@ -2,7 +2,7 @@
import React, {PureComponent} from 'react';
import {StyleSheet} from 'react-native';
import withMaterialTheme from '../styles/withMaterialTheme';
import {filterProps, LAYOUT_PROPS} from '../util';
import {withMeasurementForwarding, filterProps, LAYOUT_PROPS} from '../util';
import CircleHighlight from '../touchable/CircleHighlight';
import CoreRadio from './CoreRadio';
@@ -19,11 +19,6 @@ class Radio extends PureComponent {
this.props.onChangeChecked && this.props.onChangeChecked(!this.props.checked);
};
_setRef = (ref) => this._ref = ref;
measure(...args) { return this._ref.measure(...args); }
measureInWindow(...args) { return this._ref.measureInWindow(...args); }
measureLayout(...args) { return this._ref.measureLayout(...args); }
render() {
const {
onPress, // eslint-disable-line no-unused-vars
@@ -53,7 +48,7 @@ class Radio extends PureComponent {
// @todo Use disabled to disable ripple/press
return (
<CircleHighlight
ref={this._setRef}
ref={this._setMeasureRef}
{...rippleProps}
{...layoutProps}
pointerEvents='box-only'
@@ -69,7 +64,7 @@ class Radio extends PureComponent {
}
}
export default withMaterialTheme(Radio);
export default withMaterialTheme(withMeasurementForwarding(Radio));
const styles = StyleSheet.create({
root: {
@@ -1,17 +1,19 @@
'use strict';
import React, {PureComponent} from 'react';
import {withMeasurementForwarding} from '../util';
import CoreRipple from './CoreRipple';
/**
* A basic ripple pre-configured to fill an area without being masked
*/
export default class BorderlessRipple extends PureComponent {
export default withMeasurementForwarding(class BorderlessRipple extends PureComponent {
render() {
return (
<CoreRipple
ref={this._setMeasureRef}
borderless
maskBorderRadius={0}
{...this.props} />
);
}
}
});
@@ -1,18 +1,20 @@
'use strict';
import React, {PureComponent} from 'react';
import {withMeasurementForwarding} from '../util';
import CoreRipple from './CoreRipple';
/**
* A simple touchable with a centered circle highlight instead of a full ripple.
* Used in things like icon toggles and action bar icon buttons.
*/
export default class CircleHighlight extends PureComponent {
export default withMeasurementForwarding(class CircleHighlight extends PureComponent {
render() {
return (
<CoreRipple
ref={this._setMeasureRef}
rippleLocation='center'
maskBorderRadiusInPercent={100}
{...this.props} />
);
}
}
});
@@ -1,16 +1,18 @@
'use strict';
import React, {PureComponent} from 'react';
import {withMeasurementForwarding} from '../util';
import CoreRipple from './CoreRipple';
/**
* A basic ripple pre-configured for a circular ripple area such as a FAB
*/
export default class CircleRipple extends PureComponent {
export default withMeasurementForwarding(class CircleRipple extends PureComponent {
render() {
return (
<CoreRipple
ref={this._setMeasureRef}
maskBorderRadiusInPercent={100}
{...this.props} />
);
}
}
});
Oops, something went wrong.

0 comments on commit 65ff5ac

Please sign in to comment.