Support mobile friendly onboarding flows
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { Placement, Popper, PopperChildrenProps } from 'react-popper';
|
||||
|
||||
import { OnboardingCard } from 'ts/components/onboarding/onboarding_card';
|
||||
import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip';
|
||||
import { Animation } from 'ts/components/ui/animation';
|
||||
import { Container } from 'ts/components/ui/container';
|
||||
import { Overlay } from 'ts/components/ui/overlay';
|
||||
|
||||
@@ -22,26 +24,37 @@ export interface OnboardingFlowProps {
|
||||
isRunning: boolean;
|
||||
onClose: () => void;
|
||||
updateOnboardingStep: (stepIndex: number) => void;
|
||||
disableOverlay?: boolean;
|
||||
isMobile: boolean;
|
||||
}
|
||||
|
||||
export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
||||
public static defaultProps = {
|
||||
disableOverlay: false,
|
||||
isMobile: false,
|
||||
};
|
||||
public render(): React.ReactNode {
|
||||
if (!this.props.isRunning) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Overlay>
|
||||
let onboardingEl = null;
|
||||
if (this.props.isMobile) {
|
||||
onboardingEl = <Animation type="easeUpFromBottom">{this._renderOnboardignCard()}</Animation>;
|
||||
} else {
|
||||
onboardingEl = (
|
||||
<Popper referenceElement={this._getElementForStep()} placement={this._getCurrentStep().placement}>
|
||||
{this._renderPopperChildren.bind(this)}
|
||||
</Popper>
|
||||
</Overlay>
|
||||
);
|
||||
);
|
||||
}
|
||||
if (this.props.disableOverlay) {
|
||||
return onboardingEl;
|
||||
}
|
||||
return <Overlay>{onboardingEl}</Overlay>;
|
||||
}
|
||||
|
||||
private _getElementForStep(): Element {
|
||||
return document.querySelector(this._getCurrentStep().target);
|
||||
}
|
||||
|
||||
private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode {
|
||||
return (
|
||||
<div ref={props.ref} style={props.style} data-placement={props.placement}>
|
||||
@@ -49,7 +62,6 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private _renderToolTip(): React.ReactNode {
|
||||
const { steps, stepIndex } = this.props;
|
||||
const step = steps[stepIndex];
|
||||
@@ -72,10 +84,30 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
||||
);
|
||||
}
|
||||
|
||||
private _renderOnboardignCard(): React.ReactNode {
|
||||
const { steps, stepIndex } = this.props;
|
||||
const step = steps[stepIndex];
|
||||
const isLastStep = steps.length - 1 === stepIndex;
|
||||
return (
|
||||
<Container position="relative" zIndex={1} maxWidth="100vw">
|
||||
<OnboardingCard
|
||||
title={step.title}
|
||||
content={step.content}
|
||||
isLastStep={isLastStep}
|
||||
shouldHideBackButton={step.shouldHideBackButton}
|
||||
shouldHideNextButton={step.shouldHideNextButton}
|
||||
onClose={this.props.onClose}
|
||||
onClickNext={this._goToNextStep.bind(this)}
|
||||
onClickBack={this._goToPrevStep.bind(this)}
|
||||
continueButtonDisplay={step.continueButtonDisplay}
|
||||
continueButtonText={step.continueButtonText}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
private _getCurrentStep(): Step {
|
||||
return this.props.steps[this.props.stepIndex];
|
||||
}
|
||||
|
||||
private _goToNextStep(): void {
|
||||
const nextStep = this.props.stepIndex + 1;
|
||||
if (nextStep < this.props.steps.length) {
|
||||
@@ -84,7 +116,6 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
||||
this.props.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
private _goToPrevStep(): void {
|
||||
const nextStep = this.props.stepIndex - 1;
|
||||
if (nextStep >= 0) {
|
||||
|
Reference in New Issue
Block a user