Implement fixed position onboarding option

This commit is contained in:
fragosti
2018-07-02 18:12:08 -07:00
parent a5231df6d9
commit a31f7a5112
2 changed files with 67 additions and 33 deletions

View File

@@ -1,18 +1,35 @@
import * as _ from 'lodash';
import * as React from 'react';
import { Placement, Popper, PopperChildrenProps } from 'react-popper';
import { OnboardingCard } from 'ts/components/onboarding/onboarding_card';
import { PointerDirection } from 'ts/components/ui/pointer';
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';
import { zIndex } from 'ts/style/z_index';
export interface Step {
export interface FixedPositionSettings {
type: 'fixed';
top?: string;
bottom?: string;
left?: string;
right?: string;
pointerDirection?: PointerDirection;
}
export interface TargetPositionSettings {
type: 'target';
target: string;
placement: Placement;
}
export interface Step {
// Provide either a CSS selector, or fixed position settings. Only applies to desktop.
position: TargetPositionSettings | FixedPositionSettings;
title?: string;
content: React.ReactNode;
placement?: Placement;
shouldHideBackButton?: boolean;
shouldHideNextButton?: boolean;
continueButtonDisplay?: ContinueButtonDisplay;
@@ -40,18 +57,30 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
return null;
}
let onboardingElement = null;
const currentStep = this._getCurrentStep();
if (this.props.isMobile) {
onboardingElement = <Animation type="easeUpFromBottom">{this._renderOnboardignCard()}</Animation>;
} else {
onboardingElement = <Animation type="easeUpFromBottom">{this._renderOnboardingCard()}</Animation>;
} else if (currentStep.position.type === 'target') {
const { placement, target } = currentStep.position;
onboardingElement = (
<Popper
referenceElement={this._getElementForStep()}
placement={this._getCurrentStep().placement}
positionFixed={true}
>
<Popper referenceElement={document.querySelector(target)} placement={placement} positionFixed={true}>
{this._renderPopperChildren.bind(this)}
</Popper>
);
} else if (currentStep.position.type === 'fixed') {
const { top, right, bottom, left, pointerDirection } = currentStep.position;
onboardingElement = (
<Container
position="fixed"
zIndex={zIndex.aboveOverlay}
top={top}
right={right}
bottom={bottom}
left={left}
>
{this._renderToolTip(pointerDirection)}
</Container>
);
}
if (this.props.disableOverlay) {
return onboardingElement;
@@ -63,9 +92,6 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
</div>
);
}
private _getElementForStep(): Element {
return document.querySelector(this._getCurrentStep().target);
}
private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode {
const customStyles = { zIndex: zIndex.aboveOverlay };
// On re-render, we want to re-center the popper.
@@ -76,7 +102,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
</div>
);
}
private _renderToolTip(): React.ReactNode {
private _renderToolTip(pointerDirection?: PointerDirection): React.ReactNode {
const { steps, stepIndex } = this.props;
const step = steps[stepIndex];
const isLastStep = steps.length - 1 === stepIndex;
@@ -94,12 +120,13 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
continueButtonDisplay={step.continueButtonDisplay}
continueButtonText={step.continueButtonText}
onContinueButtonClick={step.onContinueButtonClick}
pointerDirection={pointerDirection}
/>
</Container>
);
}
private _renderOnboardignCard(): React.ReactNode {
private _renderOnboardingCard(): React.ReactNode {
const { steps, stepIndex } = this.props;
const step = steps[stepIndex];
const isLastStep = steps.length - 1 === stepIndex;

View File

@@ -9,7 +9,12 @@ import { AddEthOnboardingStep } from 'ts/components/onboarding/add_eth_onboardin
import { CongratsOnboardingStep } from 'ts/components/onboarding/congrats_onboarding_step';
import { InstallWalletOnboardingStep } from 'ts/components/onboarding/install_wallet_onboarding_step';
import { IntroOnboardingStep } from 'ts/components/onboarding/intro_onboarding_step';
import { OnboardingFlow, Step } from 'ts/components/onboarding/onboarding_flow';
import {
OnboardingFlow,
Step,
TargetPositionSettings,
FixedPositionSettings,
} from 'ts/components/onboarding/onboarding_flow';
import { SetAllowancesOnboardingStep } from 'ts/components/onboarding/set_allowances_onboarding_step';
import { UnlockWalletOnboardingStep } from 'ts/components/onboarding/unlock_wallet_onboarding_step';
import {
@@ -79,56 +84,61 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
);
}
private _getSteps(): Step[] {
const nextToWalletPosition: TargetPositionSettings = {
type: 'target',
target: '.wallet',
placement: 'right',
};
const underMetamaskExtension: FixedPositionSettings = {
type: 'fixed',
top: '30px',
right: '10px',
pointerDirection: 'top',
};
const steps: Step[] = [
{
target: '.wallet',
position: nextToWalletPosition,
title: '0x Ecosystem Setup',
content: <InstallWalletOnboardingStep />,
placement: 'right',
shouldHideBackButton: true,
shouldHideNextButton: true,
},
{
target: '.wallet',
position: underMetamaskExtension,
title: '0x Ecosystem Setup',
content: <UnlockWalletOnboardingStep />,
placement: 'right',
shouldHideBackButton: true,
shouldHideNextButton: true,
},
{
target: '.wallet',
position: nextToWalletPosition,
title: '0x Ecosystem Account Setup',
content: <IntroOnboardingStep />,
placement: 'right',
shouldHideBackButton: true,
continueButtonDisplay: 'enabled',
},
{
target: '.wallet',
position: nextToWalletPosition,
title: 'Step 1: Add ETH',
content: (
<AddEthOnboardingStep userEthBalanceInWei={this.props.userEtherBalanceInWei || new BigNumber(0)} />
),
placement: 'right',
continueButtonDisplay: this._userHasVisibleEth() ? 'enabled' : 'disabled',
},
{
target: '.wallet',
position: nextToWalletPosition,
title: 'Step 2: Wrap ETH',
content: <WrapEthOnboardingStep1 />,
placement: 'right',
continueButtonDisplay: 'enabled',
},
{
target: '.wallet',
position: nextToWalletPosition,
title: 'Step 2: Wrap ETH',
content: <WrapEthOnboardingStep2 />,
placement: 'right',
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
},
{
target: '.wallet',
position: nextToWalletPosition,
title: 'Step 2: Wrap ETH',
content: (
<WrapEthOnboardingStep3
@@ -137,11 +147,10 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
}
/>
),
placement: 'right',
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
},
{
target: '.wallet',
position: nextToWalletPosition,
title: 'Step 3: Unlock Tokens',
content: (
<SetAllowancesOnboardingStep
@@ -150,14 +159,12 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
doesUserHaveAllowancesForWethAndZrx={this._doesUserHaveAllowancesForWethAndZrx()}
/>
),
placement: 'right',
continueButtonDisplay: this._doesUserHaveAllowancesForWethAndZrx() ? 'enabled' : 'disabled',
},
{
target: '.wallet',
position: nextToWalletPosition,
title: '🎉 The Ecosystem Awaits',
content: <CongratsOnboardingStep />,
placement: 'right',
continueButtonDisplay: 'enabled',
shouldHideNextButton: true,
continueButtonText: 'Enter the 0x Ecosystem',