зеркало из https://github.com/mozilla/fxa.git
feat(payments): move source for Tooltip screen info into AppContext
Also provides ScreenInfo from src/index.tsx
This commit is contained in:
Родитель
e95012ea31
Коммит
39cc2feed0
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче