feat(payments): move source for Tooltip screen info into AppContext

Also provides ScreenInfo from src/index.tsx
This commit is contained in:
Les Orchard 2019-06-13 12:13:47 -04:00
Родитель e95012ea31
Коммит 39cc2feed0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 8679EF6E5F45416C
7 изменённых файлов: 60 добавлений и 27 удалений

Просмотреть файл

@ -3,6 +3,7 @@ import { action } from '@storybook/addon-actions';
import { StripeProvider } from 'react-stripe-elements';
import { MockLoader } from './MockLoader';
import { AppContext, AppContextType } from '../../src/lib/AppContext';
import ScreenInfo from '../../src/lib/screen-info';
declare global {
interface Window {
@ -22,6 +23,7 @@ export const defaultAppContextValue = {
config: {},
queryParams: {},
navigateToUrl: action('navigateToUrl'),
getScreenInfo: () => new ScreenInfo(window),
};
export const defaultStripeStubs = (stripe: stripe.Stripe) => {

Просмотреть файл

@ -14,6 +14,7 @@ import { AppContext } from './lib/AppContext';
import './App.scss';
import { SignInLayout, SettingsLayout } from './components/AppLayout';
import LoadingOverlay from './components/LoadingOverlay';
import ScreenInfo from './lib/screen-info';
const Product = React.lazy(() => import('./routes/Product'));
const Subscriptions = React.lazy(() => import('./routes/Subscriptions'));
@ -27,6 +28,7 @@ type AppProps = {
store: Store,
queryParams: QueryParams,
navigateToUrl: (url: string) => void,
getScreenInfo: () => ScreenInfo,
};
export const App = ({
@ -35,12 +37,14 @@ export const App = ({
store,
queryParams,
navigateToUrl,
getScreenInfo,
}: AppProps) => {
const appContextValue = {
accessToken,
config,
queryParams,
navigateToUrl,
getScreenInfo,
};
return (
<StripeProvider apiKey={config.stripe.apiKey}>

Просмотреть файл

@ -3,6 +3,7 @@ import { render, cleanup, fireEvent, } from '@testing-library/react';
import 'jest-dom/extend-expect';
import { Omit } from '../lib/types';
import ScreenInfo from '../lib/screen-info';
import { AppContext, AppContextType, defaultAppContext } from '../lib/AppContext';
import {
Tooltip,
TooltipProps,
@ -30,12 +31,19 @@ const Subject = (props: SubjectProps) => {
const screenInfo = new ScreenInfo(window);
Object.assign(screenInfo, { clientHeight, clientWidth });
const appContextValue = {
...defaultAppContext,
getScreenInfo: () => screenInfo,
};
return (
<div className="input-row">
<input ref={parentRef} name="name" type="text" className="name tooltip-below invalid" />
<Tooltip {...{ ...tooltipProps, screenInfo, parentRef }} />
</div>
<AppContext.Provider value={appContextValue}>
<div className="input-row">
<input ref={parentRef} name="name" type="text" className="name tooltip-below invalid" />
<Tooltip {...{ ...tooltipProps, parentRef }} />
</div>
</AppContext.Provider>
);
};

Просмотреть файл

@ -5,9 +5,10 @@
// This is a React version of this Bootstrap view:
// https://github.com/mozilla/fxa/blob/master/packages/fxa-content-server/app/scripts/views/tooltip.js
import React, { useEffect, useRef } from 'react';
import React, { useEffect, useRef, useContext } from 'react';
import classNames from 'classnames';
import ScreenInfo from '../lib/screen-info';
import { AppContext } from '../lib/AppContext';
export const PADDING_BELOW_TOOLTIP_PX = 2;
export const PADDING_ABOVE_TOOLTIP_PX = 4;
@ -36,10 +37,10 @@ export const Tooltip = ({
dismissible = false,
onDismiss = () => {},
extraClassNames = '',
screenInfo,
}: TooltipProps) => {
const { clientHeight, clientWidth } =
screenInfo || { clientHeight: 1000, clientWidth: 1000 };
const { getScreenInfo } = useContext(AppContext);
const screenInfo = getScreenInfo();
const { clientHeight = 1000, clientWidth = 1000 } = screenInfo || {};
const doShowBelow =
showBelow &&

Просмотреть файл

@ -5,6 +5,7 @@ import { createAppStore, actions } from './store';
import { config, readConfigFromMeta } from './lib/config';
import './index.scss';
import App from './App';
import ScreenInfo from './lib/screen-info';
async function init() {
readConfigFromMeta();
@ -24,12 +25,23 @@ async function init() {
].map(store.dispatch);
render(
<App {...{ accessToken, config, store, queryParams, navigateToUrl }} />,
<App {...{
accessToken,
config,
store,
queryParams,
navigateToUrl,
getScreenInfo,
}} />,
document.getElementById('root')
);
}
}
function getScreenInfo() {
return new ScreenInfo(window);
}
function navigateToUrl(url: string) {
// TODO: instrument with metrics & etc.
window.location.href = url;

Просмотреть файл

@ -1,18 +1,24 @@
import React from 'react';
import { Config, QueryParams } from './types';
import ScreenInfo from './screen-info';
export type AppContextType = {
accessToken: string,
config: Config,
queryParams: QueryParams,
navigateToUrl: (url: string) => void,
getScreenInfo: () => ScreenInfo,
}
const defaultContext = {
export const defaultAppContext = {
accessToken: '',
config: {},
queryParams: {},
navigateToUrl: () => {}
navigateToUrl: () => {},
getScreenInfo: () => new ScreenInfo(),
};
export const AppContext = React.createContext<AppContextType>(defaultContext);
export const AppContext =
React.createContext<AppContextType>(defaultAppContext);
export default AppContext;

Просмотреть файл

@ -7,29 +7,29 @@
// module to calculate screen dimentions given a window.
enum ScreenInfoOther {
NOT_REPORTED_VALUE = 'none',
}
class ScreenInfo {
clientHeight: number | ScreenInfoOther;
clientWidth: number | ScreenInfoOther;
devicePixelRatio: number | ScreenInfoOther;
screenHeight: number | ScreenInfoOther;
screenWidth: number | ScreenInfoOther;
clientHeight: number | undefined;
clientWidth: number | undefined;
devicePixelRatio: number | undefined;
screenHeight: number | undefined;
screenWidth: number | undefined;
constructor(win?: Window) {
if (!win) {
return;
}
constructor(win: Window) {
var documentElement = win.document.documentElement || {};
var screen = win.screen || {};
// for more information:
// http://quirksmode.org/mobile/viewports.html and
// http://quirksmode.org/mobile/viewports2.html
this.clientHeight = documentElement.clientHeight || ScreenInfoOther.NOT_REPORTED_VALUE;
this.clientWidth = documentElement.clientWidth || ScreenInfoOther.NOT_REPORTED_VALUE;
this.devicePixelRatio = win.devicePixelRatio || ScreenInfoOther.NOT_REPORTED_VALUE;
this.screenHeight = screen.height || ScreenInfoOther.NOT_REPORTED_VALUE;
this.screenWidth = screen.width || ScreenInfoOther.NOT_REPORTED_VALUE;
this.clientHeight = documentElement.clientHeight;
this.clientWidth = documentElement.clientWidth;
this.devicePixelRatio = win.devicePixelRatio;
this.screenHeight = screen.height;
this.screenWidth = screen.width;
}
}