Skip to content

Carousel - migrate to typescript #1005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 28, 2020
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,21 @@ const BACKGROUND_COLORS = [
Colors.purple60
];

class CarouselScreen extends Component {
constructor(props) {
interface Props {}

interface State {
orientation: typeof Constants.orientation;
width: number;
limitShownPages: boolean;
numberOfPagesShown: number;
currentPage: number;
autoplay: boolean;
}

class CarouselScreen extends Component<Props ,State> {
carousel = React.createRef<any>();

constructor(props: Props) {
super(props);

this.state = {
Expand Down Expand Up @@ -69,12 +82,14 @@ class CarouselScreen extends Component {
return Constants.windowWidth - Spacings.s5 * 2;
};

onChangePage = (currentPage) => {
onChangePage = (currentPage: number) => {
this.setState({currentPage});
};

onPagePress = (index) => {
this.carousel.goToPage(index, true);
onPagePress = (index: number) => {
if (this.carousel && this.carousel.current) {
this.carousel.current.goToPage(index, true);
}
};

render() {
Expand Down Expand Up @@ -108,8 +123,7 @@ class CarouselScreen extends Component {

<Carousel
key={numberOfPagesShown}
migrate
ref={(r) => (this.carousel = r)}
ref={this.carousel}
//loop
autoplay={autoplay}
onChangePage={this.onChangePage}
Expand All @@ -118,7 +132,7 @@ class CarouselScreen extends Component {
containerMarginHorizontal={Spacings.s2}
initialPage={INITIAL_PAGE}
containerStyle={{height: 160}}
pageControlPosition={'under'}
pageControlPosition={Carousel.pageControlPositions.UNDER}
pageControlProps={{onPagePress: this.onPagePress, limitShownPages}}
// showCounter
allowAccessibleLayout
Expand Down Expand Up @@ -172,6 +186,7 @@ class CarouselScreen extends Component {
}
}

// @ts-ignore
const Page = ({children, style, ...others}) => {
return (
<View {...others} style={[styles.page, style]}>
Expand Down
5 changes: 5 additions & 0 deletions generatedTypes/components/carousel/CarouselPresenter.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CarouselProps, CarouselState } from './types';
export declare function getChildrenLength(props: CarouselProps): number;
export declare function calcOffset(props: CarouselProps, state: Omit<CarouselState, 'initialOffset' | 'prevProps'>): number;
export declare function calcPageIndex(offset: number, props: CarouselProps, pageWidth: number): number;
export declare function isOutOfBounds(offset: number, props: CarouselProps, pageWidth: number): boolean;
69 changes: 69 additions & 0 deletions generatedTypes/components/carousel/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { Component, RefObject, ReactNode, Key } from 'react';
import { ScrollView, LayoutChangeEvent, NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
import { CarouselProps, CarouselState, PageControlPosition } from './types';
export { CarouselProps };
interface DefaultProps extends Partial<CarouselProps> {
}
/**
* @description: Carousel for scrolling pages horizontally
* @gif: https://media.giphy.com/media/l0HU7f8gjpRlMRhKw/giphy.gif, https://media.giphy.com/media/3oFzmcjX9OhpyckhcQ/giphy.gif
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/CarouselScreen.js
* @extends: ScrollView
* @extendsLink: https://facebook.github.io/react-native/docs/scrollview
* @notes: This is screed width Component
*/
declare class Carousel extends Component<CarouselProps, CarouselState> {
static displayName: string;
static defaultProps: DefaultProps;
static pageControlPositions: typeof PageControlPosition;
carousel: RefObject<ScrollView>;
autoplayTimer?: number;
orientationChange?: boolean;
skippedInitialScroll?: boolean;
constructor(props: CarouselProps);
static getDerivedStateFromProps(nextProps: CarouselProps, prevState: CarouselState): {
pageWidth: number;
initialOffset: {
x: number;
};
prevProps: CarouselProps;
} | {
prevProps: CarouselProps;
pageWidth?: undefined;
initialOffset?: undefined;
} | null;
componentDidMount(): void;
componentWillUnmount(): void;
componentDidUpdate(prevProps: CarouselProps): void;
onOrientationChanged: () => void;
getItemSpacings(props: CarouselProps): number;
getContainerMarginHorizontal: () => number;
getContainerPaddingVertical: () => number;
updateOffset: (animated?: boolean) => void;
startAutoPlay(): void;
stopAutoPlay(): void;
resetAutoPlay(): void;
goToPage(pageIndex: number, animated?: boolean): void;
getCalcIndex(index: number): number;
getSnapToOffsets: () => number[] | undefined;
shouldUsePageWidth(): number | false | undefined;
shouldEnablePagination(): boolean | undefined;
onContainerLayout: ({ nativeEvent: { layout: { width: containerWidth } } }: LayoutChangeEvent) => void;
shouldAllowAccessibilityLayout(): boolean | undefined;
onContentSizeChange: () => void;
onMomentumScrollEnd: () => void;
goToNextPage(): void;
onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
renderChild: (child: ReactNode, key: Key) => JSX.Element | undefined;
renderChildren(): JSX.Element[] | null | undefined;
renderPageControl(): JSX.Element | undefined;
renderCounter(): JSX.Element | undefined;
renderAccessibleLayout(): JSX.Element;
renderCarousel(): JSX.Element;
render(): JSX.Element;
}
export { Carousel };
declare const _default: React.ComponentClass<CarouselProps & {
useCustomTheme?: boolean | undefined;
}, any> & typeof Carousel;
export default _default;
89 changes: 89 additions & 0 deletions generatedTypes/components/carousel/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { StyleProp, ViewStyle, NativeSyntheticEvent, NativeScrollEvent, PointPropType } from 'react-native';
import { PageControlProps } from '../pageControl';
export declare enum PageControlPosition {
OVER = "over",
UNDER = "under"
}
export interface CarouselProps {
/**
* the first page to start with
*/
initialPage?: number;
/**
* the page width (all pages should have the same width). Does not work if passing 'loop' prop
*/
pageWidth?: number;
/**
* the spacing between the items
*/
itemSpacings?: number;
/**
* Horizontal margin for the container
*/
containerMarginHorizontal?: number;
/**
* Vertical padding for the container.
* Sometimes needed when there are overflows that are cut in Android.
*/
containerPaddingVertical?: number;
/**
* if true, will have infinite scroll
*/
loop?: boolean;
/**
* callback for when page has changed
*/
onChangePage?: (newPageIndex: number, oldPageIndex: number) => void;
/**
* callback for onScroll event of the internal ScrollView
*/
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
/**
* Should the container be animated (send the animation style via containerStyle)
*/
animated?: boolean;
/**
* the carousel style
*/
containerStyle?: StyleProp<ViewStyle>;
/**
* PageControl component props
*/
pageControlProps?: Partial<PageControlProps>;
/**
* The position of the PageControl component ['over', 'under'], otherwise it won't display
*/
pageControlPosition?: PageControlPosition;
/**
* whether to show a page counter (will not work with 'pageWidth' prop)
*/
showCounter?: boolean;
/**
* the counter's text style
*/
counterTextStyle?: StyleProp<ViewStyle>;
/**
* will block multiple pages scroll (will not work with 'pageWidth' prop)
*/
pagingEnabled?: boolean;
/**
* Whether to layout Carousel for accessibility
*/
allowAccessibleLayout?: boolean;
/**
* Whether to switch automatically between the pages
*/
autoplay?: boolean;
/**
* the amount of ms to wait before switching to the next page, in case autoplay is on
*/
autoplayInterval?: number;
}
export interface CarouselState {
containerWidth?: number;
currentPage: number;
currentStandingPage?: number;
pageWidth: number;
initialOffset: PointPropType;
prevProps: CarouselProps;
}
14 changes: 9 additions & 5 deletions generatedTypes/components/pageControl/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
export interface PageControlProps {
/**
* Limit the number of page indicators shown.
* enlargeActive prop is disabled in this state,
* When set to true there will be maximum of 7 shown.
* Only relevant when numOfPages > 5.
*/
* Limit the number of page indicators shown.
* enlargeActive prop is disabled in this state,
* When set to true there will be maximum of 7 shown.
* Only relevant when numOfPages > 5.
*/
limitShownPages?: boolean;
/**
* Additional styles for the top container
Expand Down Expand Up @@ -47,6 +47,10 @@ export interface PageControlProps {
* The space between the siblings page indicators
*/
spacing?: number;
/**
* Used to identify the pageControl in tests
*/
testID?: string;
}
declare const _default: React.ComponentClass<PageControlProps & {
useCustomTheme?: boolean | undefined;
Expand Down
2 changes: 1 addition & 1 deletion generatedTypes/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ export {default as PanResponderView, PanResponderViewPropTypes} from './componen
export {default as PanDismissibleView, PanDismissibleViewPropTypes, DismissibleAnimationPropTypes} from './components/panningViews/panDismissibleView';
export {default as Dialog, DialogProps} from './components/dialog';
export {default as PageControl, PageControlProps} from './components/pageControl';
export {default as Carousel, CarouselProps} from './components/carousel';

/* All components with manual typings */
export {
ActionSheet,
Badge,
BadgeProps,
Carousel,
ConnectionStatusBar,
Drawer,
ExpandableSection,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import _ from 'lodash';
import {CarouselProps, CarouselState} from './types';


export function getChildrenLength(props) {
export function getChildrenLength(props: CarouselProps): number {
const length = _.get(props, 'children.length') || 0;
return length;
}

export function calcOffset(props, state) {
export function calcOffset(props: CarouselProps, state: Omit<CarouselState, 'initialOffset' | 'prevProps'>) {
const {currentPage, pageWidth} = state;
const {loop, containerMarginHorizontal = 0} = props;
const actualCurrentPage = loop ? currentPage + 1 : currentPage;
Expand All @@ -16,7 +16,7 @@ export function calcOffset(props, state) {
return offset;
}

export function calcPageIndex(offset, props, pageWidth) {
export function calcPageIndex(offset: number, props: CarouselProps, pageWidth: number) {
const pagesCount = getChildrenLength(props);
const {loop} = props;
const pageIndexIncludingClonedPages = Math.round(offset / pageWidth);
Expand All @@ -30,10 +30,10 @@ export function calcPageIndex(offset, props, pageWidth) {
return actualPageIndex;
}

export function isOutOfBounds(offset, props, pageWidth) {
export function isOutOfBounds(offset: number, props: CarouselProps, pageWidth: number) {
const length = getChildrenLength(props);
const minLimit = 1;
const maxLimit = ((length + 1) * pageWidth) - 1;
const maxLimit = (length + 1) * pageWidth - 1;

return !_.inRange(offset, minLimit, maxLimit);
}
Loading