@nguyentc21/react-native-tooltip
Version:
Simple tooltip for React native app
247 lines (246 loc) • 10.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _reactNativeModalView = require("@nguyentc21/react-native-modal-view");
var _Caret = _interopRequireDefault(require("./Caret"));
var _usePosition = require("../hooks/usePosition");
var _useFinalPlacement = _interopRequireDefault(require("../hooks/useFinalPlacement"));
var _useContainerStyles = _interopRequireDefault(require("../hooks/useContainerStyles"));
var _useContentContainerStyles = _interopRequireDefault(require("../hooks/useContentContainerStyles"));
var _useOffsetViewStyles = _interopRequireDefault(require("../hooks/useOffsetViewStyles"));
var _constants = require("../constants");
var _useStableCallback = _interopRequireDefault(require("../utils/useStableCallback"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function Tooltip(props) {
const {
visible,
content,
backgroundColor = _constants.DEFAULT_TOOLTIP_BACKGROUND,
backdropColor = _constants.DEFAULT_BACKDROP_COLOR,
borderRadius = _constants.DEFAULT_BORDER_RADIUS,
placement = _constants.DEFAULT_PLACEMENT,
forcePlacement,
caretSize = _constants.DEFAULT_CARET_SIZE,
hideCaret,
offset = _constants.DEFAULT_TOOLTIP_OFFSET,
screenPadding = _constants.DEFAULT_SCREEN_PADDING,
actionType = _constants.DEFAULT_ON_PRESS_ACTION_TYPE,
expose,
extraData,
modalContainerStyle,
containerStyle,
contentContainerStyle,
onClose,
onOpen,
onDidOpen,
...pressableProps
} = props;
const _caretSize = !hideCaret ? caretSize : 0;
const {
onPress,
onLongPress
} = pressableProps;
const [tooltipContentLayoutState, setTooltipContentLayoutState] = (0, _react.useState)();
const [tooltipContainerLayoutState, setTooltipContainerLayoutState] = (0, _react.useState)();
const [targetContentLayoutState, setTargetContentLayoutState] = (0, _react.useState)();
const [visibleState, setVisibleState] = (0, _react.useState)(false);
const [safeAreaInsetsState, setSafeAreaInsetsState] = (0, _react.useState)({
top: screenPadding,
bottom: screenPadding,
left: screenPadding,
right: screenPadding
});
const [tick, bumpTick] = (0, _react.useReducer)(x => x + 1, 0);
const _visible = visible ?? visibleState;
const contentRef = (0, _react.useRef)(null);
const windowDimensions = (0, _reactNative.useWindowDimensions)();
const tooltipContentLayout = (0, _react.useMemo)(() => {
if (!tooltipContainerLayoutState || !tooltipContentLayoutState) return undefined;
return {
...tooltipContentLayoutState,
x: tooltipContainerLayoutState.x + tooltipContentLayoutState.x,
y: tooltipContainerLayoutState.y + tooltipContentLayoutState.y
};
}, [tooltipContentLayoutState, tooltipContainerLayoutState]);
const finalPlacement = (0, _useFinalPlacement.default)({
safeAreaInsets: safeAreaInsetsState,
dimension: windowDimensions,
placement,
forcePlacement,
targetContentLayout: targetContentLayoutState,
tooltipContentLayout,
borderRadius
});
const tooltipPosition = (0, _usePosition.useTooltipPosition)({
safeAreaInsets: safeAreaInsetsState,
dimension: windowDimensions,
placement: finalPlacement,
targetContentLayout: targetContentLayoutState,
tooltipContentLayout
});
const caretPosition = (0, _usePosition.useCaretPosition)({
placement: finalPlacement,
targetContentLayout: targetContentLayoutState,
tooltipContentLayout,
caretSize: _caretSize
});
const {
containerStyles,
wrapContainerStyles
} = (0, _useContainerStyles.default)({
tooltipPosition,
placement: finalPlacement
});
const contentContainerStyles = (0, _useContentContainerStyles.default)({
caretSize: _caretSize,
borderRadius
});
const offsetViewStyles = (0, _useOffsetViewStyles.default)({
caretSize: _caretSize,
placement: finalPlacement,
offset
});
const _onOpen = (0, _useStableCallback.default)(() => {
var _contentRef$current, _contentRef$current$m;
onOpen === null || onOpen === void 0 || onOpen();
_reactNative.Keyboard.dismiss();
(_contentRef$current = contentRef.current) === null || _contentRef$current === void 0 || (_contentRef$current$m = _contentRef$current.measure) === null || _contentRef$current$m === void 0 || _contentRef$current$m.call(_contentRef$current, (x, y, width, height, pageX, pageY) => {
setTargetContentLayoutState({
x,
y,
width,
height,
pageX,
pageY
});
});
});
const _onTooltipLayout = (0, _react.useCallback)(e => {
setTooltipContainerLayoutState(e.nativeEvent.layout);
}, []);
const _onTooltipContentLayout = (0, _react.useCallback)(e => {
setTooltipContentLayoutState(e.nativeEvent.layout);
}, []);
const _show = (0, _react.useCallback)(() => {
setVisibleState(true);
}, []);
const _hide = (0, _react.useCallback)(() => {
setVisibleState(false);
}, []);
const _onPress = (0, _useStableCallback.default)(e => {
_show();
onPress === null || onPress === void 0 || onPress(e);
});
const _onLongPress = (0, _useStableCallback.default)(e => {
_show();
onLongPress === null || onLongPress === void 0 || onLongPress(e);
});
const _getModalLayoutData = (0, _react.useCallback)(data => {
const {
safeAreaInsets
} = data;
setSafeAreaInsetsState({
top: screenPadding + (safeAreaInsets.top || 0),
bottom: screenPadding + (safeAreaInsets.bottom || 0),
left: screenPadding + (safeAreaInsets.left || 0),
right: screenPadding + (safeAreaInsets.right || 0)
});
}, [screenPadding]);
(0, _react.useEffect)(() => {
if (!expose) return;
const handler = {
show: _show,
hide: _hide
};
expose(handler);
return () => {
expose(undefined);
};
}, [expose, _show, _hide]);
(0, _react.useEffect)(() => {
bumpTick();
}, [extraData, tooltipPosition === null || tooltipPosition === void 0 ? void 0 : tooltipPosition.top, tooltipPosition === null || tooltipPosition === void 0 ? void 0 : tooltipPosition.bottom, tooltipPosition === null || tooltipPosition === void 0 ? void 0 : tooltipPosition.left, tooltipPosition === null || tooltipPosition === void 0 ? void 0 : tooltipPosition.right, caretPosition === null || caretPosition === void 0 ? void 0 : caretPosition.top, caretPosition === null || caretPosition === void 0 ? void 0 : caretPosition.bottom, caretPosition === null || caretPosition === void 0 ? void 0 : caretPosition.left, caretPosition === null || caretPosition === void 0 ? void 0 : caretPosition.right]);
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactNative.Pressable, _extends({
ref: contentRef
}, pressableProps, {
onPress: actionType === 'onPress' ? _onPress : undefined,
onLongPress: actionType === 'onLongPress' ? _onLongPress : undefined
})), /*#__PURE__*/_react.default.createElement(_reactNativeModalView.NestedModal, {
autoPadding: false,
bottomOffset: safeAreaInsetsState.bottom || 0,
dimension: windowDimensions,
visible: _visible,
close: _hide,
onOpen: _onOpen,
onDidOpen: onDidOpen,
onClose: onClose,
getLayoutData: _getModalLayoutData,
containerStyle: [lStyles.tooltipContainerStyle, wrapContainerStyles, modalContainerStyle],
contentContainerStyle: [lStyles.shadow10, lStyles.wrapContentContainerStyle, containerStyle],
backdropStyle: {
backgroundColor: backdropColor
},
onContainerLayout: _onTooltipLayout,
onMainContentLayout: _onTooltipContentLayout,
extraData: tick
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [containerStyles]
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: lStyles.tooltipContent
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [contentContainerStyles, contentContainerStyle, {
backgroundColor
}]
}, content)), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
style: [offsetViewStyles],
pointerEvents: 'box-none'
}, !!caretPosition && !!_caretSize && /*#__PURE__*/_react.default.createElement(_Caret.default, {
backgroundColor: backgroundColor,
size: _caretSize,
style: [lStyles.positionCaret, lStyles.caret, caretPosition]
})))));
}
const lStyles = _reactNative.StyleSheet.create({
shadow10: {
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 5
},
shadowOpacity: 0.34,
shadowRadius: 6.27,
elevation: 10
},
wrapContentContainerStyle: {
borderRadius: 0,
backgroundColor: 'transparent',
overflow: 'visible'
},
tooltipContainerStyle: {
maxHeight: '100%',
height: -1,
width: -1,
overflow: 'visible',
alignSelf: 'auto',
position: 'absolute'
},
positionCaret: {
position: 'absolute'
},
tooltipContent: {
zIndex: 2,
overflow: 'hidden'
},
caret: {
zIndex: 1
}
});
var _default = exports.default = Tooltip;
//# sourceMappingURL=Tooltip.js.map