Tooltip components
Summary: _typescript_ Reviewed By: passy, bnelo12 Differential Revision: D16830063 fbshipit-source-id: bd0cf3c109caba74ee5a8f9915d46630007702fe
This commit is contained in:
committed by
Facebook Github Bot
parent
5770a206be
commit
2a76461fb8
@@ -18,7 +18,7 @@ import {createStore} from 'redux';
|
||||
import {persistStore} from 'redux-persist';
|
||||
import reducers, {Actions, State as StoreState} from './reducers/index';
|
||||
import dispatcher from './dispatcher/index';
|
||||
import TooltipProvider from './ui/components/TooltipProvider.js';
|
||||
import TooltipProvider from './ui/components/TooltipProvider';
|
||||
import config from './utils/processConfig';
|
||||
import {stateSanitizer} from './utils/reduxDevToolsConfig';
|
||||
import {initLauncherHooks} from './utils/launcher';
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type TooltipProvider from './TooltipProvider.js';
|
||||
import type {TooltipOptions} from './TooltipProvider.js';
|
||||
|
||||
import styled from '../styled/index.js';
|
||||
import {Component} from 'react';
|
||||
|
||||
import TooltipProvider, {TooltipOptions} from './TooltipProvider';
|
||||
import styled from 'react-emotion';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const TooltipContainer = styled('div')({
|
||||
@@ -19,14 +16,14 @@ const TooltipContainer = styled('div')({
|
||||
|
||||
type TooltipProps = {
|
||||
/** Content shown in the tooltip */
|
||||
title: React$Node,
|
||||
title: React.ReactNode;
|
||||
/** Component that will show the tooltip */
|
||||
children: React$Node,
|
||||
options?: TooltipOptions,
|
||||
children: React.ReactNode;
|
||||
options?: TooltipOptions;
|
||||
};
|
||||
|
||||
type TooltipState = {
|
||||
open: boolean,
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
export default class Tooltip extends Component<TooltipProps, TooltipState> {
|
||||
@@ -35,10 +32,10 @@ export default class Tooltip extends Component<TooltipProps, TooltipState> {
|
||||
};
|
||||
|
||||
context: {
|
||||
TOOLTIP_PROVIDER: TooltipProvider,
|
||||
TOOLTIP_PROVIDER: TooltipProvider;
|
||||
};
|
||||
|
||||
ref: ?HTMLDivElement;
|
||||
ref: HTMLDivElement | null;
|
||||
|
||||
state = {
|
||||
open: false,
|
||||
@@ -66,7 +63,7 @@ export default class Tooltip extends Component<TooltipProps, TooltipState> {
|
||||
this.setState({open: false});
|
||||
};
|
||||
|
||||
setRef = (ref: ?HTMLDivElement) => {
|
||||
setRef = (ref: HTMLDivElement | null) => {
|
||||
this.ref = ref;
|
||||
};
|
||||
|
||||
@@ -5,11 +5,24 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '../styled/index.js';
|
||||
import {colors} from './colors.tsx';
|
||||
import styled from 'react-emotion';
|
||||
import {colors} from './colors';
|
||||
import {Component} from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
TopProperty,
|
||||
LeftProperty,
|
||||
BottomProperty,
|
||||
RightProperty,
|
||||
BackgroundColorProperty,
|
||||
LineHeightProperty,
|
||||
PaddingProperty,
|
||||
BorderRadiusProperty,
|
||||
MaxWidthProperty,
|
||||
ColorProperty,
|
||||
WidthProperty,
|
||||
} from 'csstype';
|
||||
import React from 'react';
|
||||
|
||||
const defaultOptions = {
|
||||
backgroundColor: colors.blueGrey,
|
||||
@@ -25,19 +38,34 @@ const defaultOptions = {
|
||||
};
|
||||
|
||||
export type TooltipOptions = {
|
||||
backgroundColor?: string,
|
||||
position?: 'below' | 'above' | 'toRight' | 'toLeft',
|
||||
color?: string,
|
||||
showTail?: boolean,
|
||||
maxWidth?: string,
|
||||
width?: string,
|
||||
borderRadius?: number,
|
||||
padding?: string,
|
||||
lineHeight?: string,
|
||||
delay?: number, // in milliseconds
|
||||
backgroundColor?: string;
|
||||
position?: 'below' | 'above' | 'toRight' | 'toLeft';
|
||||
color?: string;
|
||||
showTail?: boolean;
|
||||
maxWidth?: string;
|
||||
width?: string;
|
||||
borderRadius?: number;
|
||||
padding?: string;
|
||||
lineHeight?: string;
|
||||
delay?: number; // in milliseconds
|
||||
};
|
||||
|
||||
const TooltipBubble = styled('div')(props => ({
|
||||
const TooltipBubble = styled('div')(
|
||||
(props: {
|
||||
top: TopProperty<number>;
|
||||
left: LeftProperty<number>;
|
||||
bottom: BottomProperty<number>;
|
||||
right: RightProperty<number>;
|
||||
options: {
|
||||
backgroundColor: BackgroundColorProperty;
|
||||
lineHeight: LineHeightProperty<number>;
|
||||
padding: PaddingProperty<number>;
|
||||
borderRadius: BorderRadiusProperty<number>;
|
||||
width: WidthProperty<number>;
|
||||
maxWidth: MaxWidthProperty<number>;
|
||||
color: ColorProperty;
|
||||
};
|
||||
}) => ({
|
||||
position: 'absolute',
|
||||
zIndex: 99999999999,
|
||||
backgroundColor: props.options.backgroundColor,
|
||||
@@ -51,7 +79,8 @@ const TooltipBubble = styled('div')(props => ({
|
||||
bottom: props.bottom,
|
||||
right: props.right,
|
||||
color: props.options.color,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
// vertical offset on bubble when position is 'below'
|
||||
const BUBBLE_BELOW_POSITION_VERTICAL_OFFSET = -10;
|
||||
@@ -64,7 +93,16 @@ const TAIL_AB_POSITION_HORIZONTAL_OFFSET = 15;
|
||||
// vertical offset on tail when position is 'toLeft' or 'toRight'
|
||||
const TAIL_LR_POSITION_HORIZONTAL_OFFSET = 5;
|
||||
|
||||
const TooltipTail = styled('div')(props => ({
|
||||
const TooltipTail = styled('div')(
|
||||
(props: {
|
||||
top: TopProperty<number>;
|
||||
left: LeftProperty<number>;
|
||||
bottom: BottomProperty<number>;
|
||||
right: RightProperty<number>;
|
||||
options: {
|
||||
backgroundColor: BackgroundColorProperty;
|
||||
};
|
||||
}) => ({
|
||||
position: 'absolute',
|
||||
display: 'block',
|
||||
whiteSpace: 'pre',
|
||||
@@ -78,26 +116,27 @@ const TooltipTail = styled('div')(props => ({
|
||||
left: props.left,
|
||||
bottom: props.bottom,
|
||||
right: props.right,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
type TooltipProps = {
|
||||
children: React$Node,
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
type TooltipObject = {
|
||||
rect: ClientRect,
|
||||
title: React$Node,
|
||||
options: TooltipOptions,
|
||||
rect: ClientRect;
|
||||
title: React.ReactNode;
|
||||
options: TooltipOptions;
|
||||
};
|
||||
|
||||
type TooltipState = {
|
||||
tooltip: ?TooltipObject,
|
||||
timeoutID: ?TimeoutID,
|
||||
tooltip: TooltipObject | null | undefined;
|
||||
timeoutID: ReturnType<typeof setTimeout> | null | undefined;
|
||||
};
|
||||
|
||||
export default class TooltipProvider extends Component<
|
||||
TooltipProps,
|
||||
TooltipState,
|
||||
TooltipState
|
||||
> {
|
||||
static childContextTypes = {
|
||||
TOOLTIP_PROVIDER: PropTypes.object,
|
||||
@@ -112,7 +151,11 @@ export default class TooltipProvider extends Component<
|
||||
return {TOOLTIP_PROVIDER: this};
|
||||
}
|
||||
|
||||
open(container: HTMLDivElement, title: React$Node, options: TooltipOptions) {
|
||||
open(
|
||||
container: HTMLDivElement,
|
||||
title: React.ReactNode,
|
||||
options: TooltipOptions,
|
||||
) {
|
||||
const node = container.childNodes[0];
|
||||
if (node == null || !(node instanceof HTMLElement)) {
|
||||
return;
|
||||
@@ -153,10 +196,10 @@ export default class TooltipProvider extends Component<
|
||||
return null;
|
||||
}
|
||||
|
||||
let left = 'auto';
|
||||
let top = 'auto';
|
||||
let bottom = 'auto';
|
||||
let right = 'auto';
|
||||
let left: LeftProperty<number> = 'auto';
|
||||
let top: TopProperty<number> = 'auto';
|
||||
let bottom: BottomProperty<number> = 'auto';
|
||||
let right: RightProperty<number> = 'auto';
|
||||
|
||||
if (opts.position === 'below') {
|
||||
left = tooltip.rect.left + TAIL_AB_POSITION_HORIZONTAL_OFFSET;
|
||||
@@ -189,10 +232,10 @@ export default class TooltipProvider extends Component<
|
||||
|
||||
getTooltipBubble(tooltip: TooltipObject) {
|
||||
const opts = Object.assign(defaultOptions, tooltip.options);
|
||||
let left = 'auto';
|
||||
let top = 'auto';
|
||||
let bottom = 'auto';
|
||||
let right = 'auto';
|
||||
let left: LeftProperty<number> = 'auto';
|
||||
let top: TopProperty<number> = 'auto';
|
||||
let bottom: BottomProperty<number> = 'auto';
|
||||
let right: RightProperty<number> = 'auto';
|
||||
|
||||
if (opts.position === 'below') {
|
||||
left = tooltip.rect.left;
|
||||
@@ -8,7 +8,7 @@
|
||||
import DataDescription from './DataDescription.js';
|
||||
import {Component} from 'react';
|
||||
import ContextMenu from '../ContextMenu.js';
|
||||
import Tooltip from '../Tooltip.js';
|
||||
import Tooltip from '../Tooltip.tsx';
|
||||
import styled from '../../styled/index.js';
|
||||
import DataPreview from './DataPreview.js';
|
||||
import createPaste from '../../../fb-stubs/createPaste.tsx';
|
||||
|
||||
@@ -130,8 +130,8 @@ export {default as TextParagraph} from './components/TextParagraph.tsx';
|
||||
export {default as Link} from './components/Link.js';
|
||||
export {default as PathBreadcrumbs} from './components/PathBreadcrumbs.tsx';
|
||||
export {default as ModalOverlay} from './components/ModalOverlay.tsx';
|
||||
export {default as Tooltip} from './components/Tooltip.js';
|
||||
export {default as TooltipProvider} from './components/TooltipProvider.js';
|
||||
export {default as Tooltip} from './components/Tooltip.tsx';
|
||||
export {default as TooltipProvider} from './components/TooltipProvider.tsx';
|
||||
export {default as ResizeSensor} from './components/ResizeSensor.tsx';
|
||||
export {default as StatusIndicator} from './components/StatusIndicator.tsx';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user