Skip to content

Commit 050ddab

Browse files
committed
Move PageControl to typescript - initial commit
1 parent b63ef36 commit 050ddab

File tree

4 files changed

+109
-41
lines changed

4 files changed

+109
-41
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react';
2+
import { StyleProp, ViewStyle } from 'react-native';
3+
export interface PageControlProps {
4+
/**
5+
* Limit the number of page indicators shown.
6+
* enlargeActive prop is disabled in this state,
7+
* When set to true there will be maximum of 7 shown.
8+
* Only relevant when numOfPages > 5.
9+
*/
10+
limitShownPages?: boolean;
11+
/**
12+
* Additional styles for the top container
13+
*/
14+
containerStyle?: StyleProp<ViewStyle>;
15+
/**
16+
* Total number of pages
17+
*/
18+
numOfPages: number;
19+
/**
20+
* Zero-based index of the current page
21+
*/
22+
currentPage: number;
23+
/**
24+
* Action handler for clicking on a page indicator
25+
*/
26+
onPagePress?: (index: number) => void;
27+
/**
28+
* Color of the selected page dot and, if inactiveColor not passed, the border of the not selected pages
29+
*/
30+
color?: string;
31+
/**
32+
* Color of the unselected page dots and the border of the not selected pages
33+
*/
34+
inactiveColor?: string;
35+
/**
36+
* The size of the page indicator.
37+
* When setting limitShownPages the medium sized will be 2/3 of size and the small will be 1/3 of size.
38+
* An alternative is to send an array [smallSize, mediumSize, largeSize].
39+
*/
40+
size?: number | [number, number, number];
41+
/**
42+
* Whether to enlarge the active page indicator
43+
* Irrelevant when limitShownPages is in effect.
44+
*/
45+
enlargeActive?: boolean;
46+
/**
47+
* The space between the siblings page indicators
48+
*/
49+
spacing?: number;
50+
}
51+
declare const _default: React.ComponentClass<PageControlProps & {
52+
useCustomTheme?: boolean | undefined;
53+
}, any>;
54+
export default _default;

generatedTypes/components/touchableOpacity/index.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { TouchableOpacityProps as RNTouchableOpacityProps, StyleProp, ViewStyle, Animated } from 'react-native';
33
import { ContainerModifiers } from '../../commons/new';
4-
export declare type TouchableOpacityProps = Omit<RNTouchableOpacityProps, 'style'> & ContainerModifiers & {
4+
export declare type TouchableOpacityProps = Omit<RNTouchableOpacityProps, 'style' | 'onPress'> & ContainerModifiers & {
55
/**
66
* background color for TouchableOpacity
77
*/
@@ -31,8 +31,9 @@ export declare type TouchableOpacityProps = Omit<RNTouchableOpacityProps, 'style
3131
customValue?: any;
3232
ref?: any;
3333
style?: StyleProp<ViewStyle> | Animated.AnimatedProps<StyleProp<ViewStyle>>;
34+
onPress?: (props: TouchableOpacityProps) => void;
3435
};
35-
declare const _default: React.ComponentClass<Pick<RNTouchableOpacityProps, "testID" | "disabled" | "activeOpacity" | "onPress" | "onLongPress" | "hitSlop" | "onLayout" | "hasTVPreferredFocus" | "tvParallaxProperties" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityRole" | "accessibilityStates" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityComponentType" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityTraits" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "delayLongPress" | "delayPressIn" | "delayPressOut" | "onBlur" | "onFocus" | "onPressIn" | "onPressOut" | "pressRetentionOffset"> & Partial<Record<import("../../commons/modifiers").AlignmentLiterals, boolean>> & Partial<Record<import("../../commons/modifiers").PositionLiterals, boolean>> & Partial<Record<"padding" | "paddingL" | "paddingT" | "paddingR" | "paddingB" | "paddingH" | "paddingV", boolean>> & Partial<Record<"margin" | "marginL" | "marginT" | "marginR" | "marginB" | "marginH" | "marginV", boolean>> & Partial<Record<"flex" | "flexG" | "flexS", boolean>> & Partial<Record<"br0" | "br10" | "br20" | "br30" | "br40" | "br50" | "br60" | "br100", boolean>> & Partial<Record<"bg", boolean>> & {
36+
declare const _default: React.ComponentClass<Pick<RNTouchableOpacityProps, "testID" | "onLayout" | "hitSlop" | "hasTVPreferredFocus" | "tvParallaxProperties" | "accessible" | "accessibilityActions" | "accessibilityLabel" | "accessibilityRole" | "accessibilityStates" | "accessibilityState" | "accessibilityHint" | "accessibilityValue" | "onAccessibilityAction" | "accessibilityComponentType" | "accessibilityLiveRegion" | "importantForAccessibility" | "accessibilityElementsHidden" | "accessibilityTraits" | "accessibilityViewIsModal" | "onAccessibilityEscape" | "onAccessibilityTap" | "onMagicTap" | "accessibilityIgnoresInvertColors" | "disabled" | "activeOpacity" | "onLongPress" | "delayLongPress" | "delayPressIn" | "delayPressOut" | "onBlur" | "onFocus" | "onPressIn" | "onPressOut" | "pressRetentionOffset"> & Partial<Record<import("../../commons/modifiers").AlignmentLiterals, boolean>> & Partial<Record<import("../../commons/modifiers").PositionLiterals, boolean>> & Partial<Record<"padding" | "paddingL" | "paddingT" | "paddingR" | "paddingB" | "paddingH" | "paddingV", boolean>> & Partial<Record<"margin" | "marginL" | "marginT" | "marginR" | "marginB" | "marginH" | "marginV", boolean>> & Partial<Record<"flex" | "flexG" | "flexS", boolean>> & Partial<Record<"br0" | "br10" | "br20" | "br30" | "br40" | "br50" | "br60" | "br100", boolean>> & Partial<Record<"bg", boolean>> & {
3637
/**
3738
* background color for TouchableOpacity
3839
*/
@@ -62,6 +63,7 @@ declare const _default: React.ComponentClass<Pick<RNTouchableOpacityProps, "test
6263
customValue?: any;
6364
ref?: any;
6465
style?: false | ViewStyle | import("react-native").RegisteredStyle<ViewStyle> | import("react-native").RecursiveArray<false | ViewStyle | import("react-native").RegisteredStyle<ViewStyle> | null | undefined> | Animated.AnimatedProps<ViewStyle> | Animated.AnimatedProps<import("react-native").RegisteredStyle<ViewStyle>> | Animated.AnimatedProps<import("react-native").RecursiveArray<false | ViewStyle | import("react-native").RegisteredStyle<ViewStyle> | null | undefined>> | null | undefined;
66+
onPress?: ((props: TouchableOpacityProps) => void) | undefined;
6567
} & {
6668
useCustomTheme?: boolean | undefined;
6769
}, any>;

src/components/pageControl/index.tsx

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,95 @@
11
import _ from 'lodash';
2-
import PropTypes from 'prop-types';
32
import React, {PureComponent} from 'react';
4-
import {StyleSheet, LayoutAnimation} from 'react-native';
5-
import {asBaseComponent, forwardRef} from '../../commons';
3+
import {StyleSheet, LayoutAnimation, StyleProp, ViewStyle} from 'react-native';
4+
import {asBaseComponent, forwardRef} from '../../commons/new';
65
import {Colors} from '../../style';
7-
import TouchableOpacity from '../touchableOpacity';
6+
import TouchableOpacity, {TouchableOpacityProps} from '../touchableOpacity';
87
import View from '../view';
98

109
const MAX_SHOWN_PAGES = 7;
1110
const NUM_LARGE_INDICATORS = 3;
1211
const DEFAULT_INDICATOR_COLOR = Colors.blue30;
1312

14-
function getColorStyle(color, inactiveColor, isCurrentPage) {
13+
function getColorStyle(isCurrentPage: boolean, color?: string, inactiveColor?: string) {
1514
const activeColor = color || DEFAULT_INDICATOR_COLOR;
1615
return {
1716
borderColor: isCurrentPage ? activeColor : inactiveColor || activeColor,
1817
backgroundColor: isCurrentPage ? activeColor : inactiveColor || 'transparent'
1918
};
2019
}
2120

22-
function getSizeStyle(size, enlargeActive, index, currentPage) {
21+
function getSizeStyle(size: number, index: number, currentPage: number, enlargeActive?: boolean) {
2322
const temp = enlargeActive ? (index === currentPage ? size + 2 : size) : size;
2423
return {width: temp, height: temp, borderRadius: temp / 2};
2524
}
2625

26+
function getNumberOfPagesShown(props: PageControlProps) {
27+
return Math.min(MAX_SHOWN_PAGES, props.numOfPages);
28+
}
29+
30+
export interface PageControlProps {
2731
/**
28-
* @description: Page indicator, typically used in paged scroll-views
29-
* @image: https://user-images.githubusercontent.com/33805983/34663655-76698110-f460-11e7-854b-243d27f66fec.png
30-
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/PageControlScreen.js
31-
*/
32-
class PageControl extends PureComponent {
33-
static displayName = 'PageControl';
34-
static propTypes = {
35-
/**
3632
* Limit the number of page indicators shown.
3733
* enlargeActive prop is disabled in this state,
3834
* When set to true there will be maximum of 7 shown.
3935
* Only relevant when numOfPages > 5.
4036
*/
41-
limitShownPages: PropTypes.bool,
37+
limitShownPages?: boolean;
4238
/**
4339
* Additional styles for the top container
4440
*/
45-
containerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
41+
containerStyle?: StyleProp<ViewStyle>;
4642
/**
4743
* Total number of pages
4844
*/
49-
numOfPages: PropTypes.number,
45+
numOfPages: number;
5046
/**
5147
* Zero-based index of the current page
5248
*/
53-
currentPage: PropTypes.number,
49+
currentPage: number;
5450
/**
5551
* Action handler for clicking on a page indicator
5652
*/
57-
onPagePress: PropTypes.func,
53+
onPagePress?: (index: number) => void;
5854
/**
5955
* Color of the selected page dot and, if inactiveColor not passed, the border of the not selected pages
6056
*/
61-
color: PropTypes.string,
57+
color?: string;
6258
/**
6359
* Color of the unselected page dots and the border of the not selected pages
6460
*/
65-
inactiveColor: PropTypes.string,
61+
inactiveColor?: string;
6662
/**
6763
* The size of the page indicator.
6864
* When setting limitShownPages the medium sized will be 2/3 of size and the small will be 1/3 of size.
6965
* An alternative is to send an array [smallSize, mediumSize, largeSize].
7066
*/
71-
size: PropTypes.oneOfType([PropTypes.number, PropTypes.array]),
67+
size?: number | [number, number, number];
7268
/**
7369
* Whether to enlarge the active page indicator
7470
* Irrelevant when limitShownPages is in effect.
7571
*/
76-
enlargeActive: PropTypes.bool,
72+
enlargeActive?: boolean;
7773
/**
7874
* The space between the siblings page indicators
7975
*/
80-
spacing: PropTypes.number
81-
};
76+
spacing?: number;
77+
}
78+
79+
interface State {
80+
numOfPagesShown: number;
81+
largeIndicatorsOffset: number;
82+
pagesOffset: number;
83+
prevPage?: number;
84+
}
85+
86+
/**
87+
* @description: Page indicator, typically used in paged scroll-views
88+
* @image: https://user-images.githubusercontent.com/33805983/34663655-76698110-f460-11e7-854b-243d27f66fec.png
89+
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/PageControlScreen.js
90+
*/
91+
class PageControl extends PureComponent<PageControlProps, State> {
92+
static displayName = 'PageControl';
8293

8394
static DEFAULT_SIZE = 10;
8495
static DEFAULT_SPACING = 4;
@@ -87,11 +98,11 @@ class PageControl extends PureComponent {
8798
enlargeActive: false
8899
};
89100

90-
constructor(props) {
101+
constructor(props: PageControlProps) {
91102
super(props);
92103

93104
this.state = {
94-
numOfPagesShown: Math.min(MAX_SHOWN_PAGES, props.numOfPages),
105+
numOfPagesShown: getNumberOfPagesShown(props),
95106
largeIndicatorsOffset: 0,
96107
pagesOffset: 0,
97108
prevPage: undefined
@@ -109,10 +120,10 @@ class PageControl extends PureComponent {
109120
}
110121
}
111122

112-
static getDerivedStateFromProps(nextProps, prevState) {
123+
static getDerivedStateFromProps(nextProps: PageControlProps, prevState: State) {
113124
const {currentPage} = nextProps;
114125
const {largeIndicatorsOffset: prevLargeIndicatorsOffset, prevPage} = prevState;
115-
const newState = {};
126+
const newState: {prevPage?: number, pagesOffset?: number, largeIndicatorsOffset?: number} = {};
116127

117128
if (currentPage !== prevPage) {
118129
newState.prevPage = currentPage;
@@ -130,17 +141,17 @@ class PageControl extends PureComponent {
130141
return _.isEmpty(newState) ? null : newState;
131142
}
132143

133-
static animate(props) {
144+
static animate(props: PageControlProps) {
134145
if (PageControl.showLimitedVersion(props)) {
135146
LayoutAnimation.configureNext({...LayoutAnimation.Presets.linear, duration: 100});
136147
}
137148
}
138149

139-
static showLimitedVersion({limitShownPages, numOfPages}) {
150+
static showLimitedVersion({limitShownPages, numOfPages}: PageControlProps) {
140151
return limitShownPages && numOfPages > 5;
141152
}
142153

143-
getSize(index) {
154+
getSize(index: number): undefined | number {
144155
const {largeIndicatorsOffset} = this.state;
145156
const {numOfPages} = this.props;
146157
let mediumSize,
@@ -166,23 +177,23 @@ class PageControl extends PureComponent {
166177
}
167178
}
168179

169-
onPagePress = ({index}) => {
180+
onPagePress = ({customValue: index}: TouchableOpacityProps) => {
170181
PageControl.animate(this.props);
171182
_.invoke(this.props, 'onPagePress', index);
172183
};
173184

174-
renderIndicator(index, size, enlargeActive) {
185+
renderIndicator(index: number, size: number, enlargeActive?: boolean) {
175186
const {currentPage, color, inactiveColor, onPagePress, spacing = PageControl.DEFAULT_SPACING} = this.props;
176187
return (
177188
<TouchableOpacity
178-
index={index}
189+
customValue={index}
179190
onPress={onPagePress && this.onPagePress}
180191
key={index}
181192
style={[
182193
styles.pageIndicator,
183194
{marginHorizontal: spacing / 2},
184-
getColorStyle(color, inactiveColor, index === currentPage),
185-
getSizeStyle(size, enlargeActive, index, currentPage)
195+
getColorStyle(index === currentPage, color, inactiveColor),
196+
getSizeStyle(size, index, currentPage, enlargeActive)
186197
]}
187198
/>
188199
);
@@ -220,7 +231,7 @@ class PageControl extends PureComponent {
220231
}
221232
}
222233

223-
export default asBaseComponent(forwardRef(PageControl));
234+
export default asBaseComponent<PageControlProps>(forwardRef(PageControl));
224235

225236
const styles = StyleSheet.create({
226237
container: {

src/components/touchableOpacity/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import IncubatorTouchableOpacity from '../../incubator/TouchableOpacity';
1919

2020

21-
export type TouchableOpacityProps = Omit<RNTouchableOpacityProps, 'style'> &
21+
export type TouchableOpacityProps = Omit<RNTouchableOpacityProps, 'style' | 'onPress'> &
2222
ContainerModifiers & {
2323
/**
2424
* background color for TouchableOpacity
@@ -46,6 +46,7 @@ export type TouchableOpacityProps = Omit<RNTouchableOpacityProps, 'style'> &
4646
customValue?: any;
4747
ref?: any;
4848
style?: StyleProp<ViewStyle> | Animated.AnimatedProps<StyleProp<ViewStyle>>;
49+
onPress?: (props: TouchableOpacityProps) => void;
4950
};
5051

5152
type Props = BaseComponentInjectedProps &

0 commit comments

Comments
 (0)