import * as React from 'react'; export type ReactComponent

= React.StatelessComponent

| React.ComponentClass

; const { isValidElement } = React; export const firstChild = () => (props: {children?: React.ReactNode}) => { const childrenArray = React.Children.toArray(props.children); return childrenArray[0] || null; }; export const getDisplayName = () => (COMPONENT: ReactComponent) => { return COMPONENT.displayName || (COMPONENT as React.StatelessComponent).name || 'COMPONENT'; }; /// Wraps `element` in `Component`, if it is not already an instance of /// `Component`. If `props` is passed, those will be added as props on the /// wrapped component. If `element` is null, the component is not wrapped. export function wrapWithComponent

( element: React.ReactNode | null | undefined, COMPONENT: ReactComponent

, props?: any ): React.ReactNode { if (element == null) { return null; } return isElementOfType(element, COMPONENT) ? element as React.ReactElement

: {element}; } /// In development, we compare based on the name of the function because /// React Hot Loader proxies React components in order to make updates. In /// production we can simply compare the components for equality. const isComponent = (aComponent: ReactComponent, anotherComponent: ReactComponent): boolean => { if (aComponent.displayName && anotherComponent.displayName) { const isAComponentThemed = aComponent.displayName.indexOf('Themed') === 0; const isAnotherComponentThemed = anotherComponent.displayName.indexOf('Themed') === 0; if ((isAComponentThemed && !isAnotherComponentThemed) || (!isAComponentThemed && isAnotherComponentThemed)) { return false; } return aComponent.displayName === anotherComponent.displayName; } return aComponent === anotherComponent; }; /// Checks whether `element` is a React element of type `Component` (or one of /// the passed components, if `Component` is an array of React components). export function isElementOfType( element: React.ReactNode | null | undefined, component: ReactComponent<{}> | ReactComponent<{}>[] ): boolean { if (element == null || !isValidElement(element) || typeof element.type === 'string') { return false; } const { type } = element; const components = Array.isArray(component) ? component : [component]; return components.some(aComponent => typeof type !== 'string' && isComponent(aComponent, type)); } // Function to calculate position of tooltip or popover export function calculateTipPosition(activatorRectXAxisCenter: number, left: number, preferredPosition?: any, preferredAlignment?: any) { if (preferredAlignment === 'right' && preferredPosition === 'below') { return { marginLeft: activatorRectXAxisCenter, marginTop: '-4px' }; } if (preferredAlignment === 'center' && preferredPosition === 'below') { return { marginLeft: (activatorRectXAxisCenter / 2) + 8, marginTop: '-4px' }; } if (preferredAlignment === 'left' && preferredPosition === 'below') { return { marginLeft: 16, marginTop: '-4px' }; } if (preferredAlignment === 'left' && preferredPosition === 'above') { return { marginLeft: 10 }; } if (preferredPosition === 'above') { return { marginLeft: activatorRectXAxisCenter }; } if (preferredPosition === 'below' || preferredPosition === 'mostSpace') { return { marginLeft: activatorRectXAxisCenter, marginTop: '-4px' }; } if (preferredPosition === 'belowLeft') { return { marginLeft: activatorRectXAxisCenter, marginTop: '-4px' }; } if (preferredPosition === 'belowRight') { return { left: activatorRectXAxisCenter - left, marginTop: '-4px' }; } if (preferredPosition === 'right') { return { top: '34%' }; } if (preferredPosition === 'left') { return { top: '34%', right: '4%' }; } }