UNPKG

@prosperitainova/dumbo-react-native

Version:
213 lines (209 loc) 6.17 kB
"use strict"; import React from 'react'; import { StyleSheet, View, Pressable, Modal as ReactModal, Dimensions } from 'react-native'; import { getColor, shadowStyle } from '../../styles/colors'; import { styleReferenceBreaker } from '../../helpers'; import { modalPresentations } from '../../constants/constants'; import { zIndexes } from '../../styles/z-index'; import { defaultText } from '../../constants/defaultText'; import { Button } from '../Button'; import { Link } from '../Link'; /** Positions for the caret on tooltips */ /** Props for Tooltip component */ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /** * Tooltip component for rendering a tooltip popup * * {@link https://github.com/carbon-design-system/carbon-react-native/blob/main/example/src/Views/Tooltip.tsx | Example code} */ export class Tooltip extends React.Component { state = { open: false, renderLeft: 0, renderTop: 0, renderBottom: 0, inverseMenu: false }; get styles() { const { renderLeft, renderTop, renderBottom, inverseMenu } = this.state; const caret = { width: 12, height: 12, backgroundColor: getColor('backgroundInverse'), position: 'absolute', top: inverseMenu ? undefined : -6, bottom: inverseMenu ? -6 : undefined, transform: [{ rotate: '45deg' }], right: undefined, left: 18 }; switch (this.caretPosition) { case 'center': caret.right = '50%'; caret.left = '50%'; break; case 'right': caret.right = 18; caret.left = undefined; break; } return StyleSheet.create({ modal: { zIndex: zIndexes.dropdown }, wrapper: {}, closeModal: { zIndex: zIndexes.behind, top: 0, right: 0, bottom: 0, left: 0, position: 'absolute' }, tooltipWrapper: { backgroundColor: getColor('backgroundInverse'), maxWidth: 336, padding: 16, borderRadius: 2, position: 'absolute', top: renderTop, bottom: renderBottom, left: renderLeft, ...shadowStyle }, caret: caret }); } toggleTooltip = () => { const { open } = this.state; this.setState({ open: !open }); }; closeTooltip = () => { this.setState({ open: false }); }; get height() { const { height } = this.props; return height || 200; } get caretPosition() { const { caretPosition } = this.props; return caretPosition || 'left'; } /** * Calculate where to render the overlayed tooltip * Sometimes didMount is not called before full render and results in all 0. setTimeout waits for load * * In event measure returns bad it will load to top of page with min width/height. * * @param item - View from reference */ setFormItemRef = item => { if (item && typeof item?.measure === 'function') { setTimeout(() => { const { renderLeft, renderTop, renderBottom, inverseMenu } = this.state; const screenHeight = Dimensions.get('window').height || 320; const caretSize = 12; item.measure((_fx, _fy, _width, height, pageX, pageY) => { const newRenderLeft = pageX || 0; let newRenderTop = (pageY || 0) + (height || 200) + caretSize; let newRenderBottom = screenHeight - (newRenderTop + this.height); let newInverse = false; if (newRenderTop > screenHeight - this.height) { newRenderBottom = screenHeight - (pageY || 0) + caretSize; newRenderTop = screenHeight - (newRenderBottom + this.height); newInverse = true; } if (screenHeight - (newRenderBottom + newRenderTop) < this.height) { if (newInverse) { newRenderTop = 44; } else { newRenderBottom = 44; } } if (renderLeft !== newRenderLeft || renderTop !== newRenderTop || renderBottom !== newRenderBottom || inverseMenu !== newInverse) { this.setState({ renderLeft: newRenderLeft, renderTop: newRenderTop, renderBottom: newRenderBottom, inverseMenu: newInverse }); } }); }); } }; render() { const { content, componentProps, style, contentStyle, linkProps, buttonProps, closeText } = this.props; const { open } = this.state; return /*#__PURE__*/_jsx(View, { style: styleReferenceBreaker(this.styles.wrapper, style), accessibilityRole: "menu", ...(componentProps || {}), children: /*#__PURE__*/_jsxs(View, { children: [linkProps ? /*#__PURE__*/_jsx(Link, { ...linkProps, onPress: this.toggleTooltip, forwardRef: this.setFormItemRef }) : /*#__PURE__*/_jsx(Button, { ...(buttonProps || { text: '' }), overrideColor: buttonProps?.iconOnlyMode ? open ? getColor('iconPrimary') : getColor('iconSecondary') : undefined, onPress: this.toggleTooltip, forwardRef: this.setFormItemRef }), open && /*#__PURE__*/_jsxs(ReactModal, { style: this.styles.modal, supportedOrientations: modalPresentations, transparent: true, onRequestClose: () => this.setState({ open: false }), children: [/*#__PURE__*/_jsx(Pressable, { style: this.styles.closeModal, accessibilityRole: "button", accessibilityLabel: closeText || defaultText.close, onPress: this.closeTooltip }), /*#__PURE__*/_jsxs(View, { style: styleReferenceBreaker(this.styles.tooltipWrapper, contentStyle), children: [/*#__PURE__*/_jsx(View, { style: this.styles.caret }), content] })] })] }) }); } } //# sourceMappingURL=index.js.map