UNPKG

react-native-web-ui-components

Version:

[![Dependencies](https://img.shields.io/badge/dependencies-renovate-brightgreen.svg)](https://github.com/CareLuLu/react-native-web-ui-components/issues/12) [![Codacy Badge](https://img.shields.io/codacy/grade/c0ef990240a84ab7abee7af64602dd6d/master)](http

166 lines (149 loc) 3.99 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import React from 'react'; import { StyleSheet, Text } from 'react-native'; import PropTypes from 'prop-types'; import StylePropType from '../StylePropType'; import { useAmp } from '../Amp'; import { withTheme } from '../Theme'; import { useHistory } from '../History'; const PROTOCOL_REGEX = /^[a-zA-Z\-_]+:\/\//; const styles = StyleSheet.create({ empty: {}, defaults: { fontSize: 13, lineHeight: '20px' }, fullWidth: { width: '100%' }, noLineHeight: { lineHeight: 0 } }); const go = ({ to, history, external, replace }) => e => { let href = to; if (!external) { e.nativeEvent.preventDefault(); } else if (!PROTOCOL_REGEX.test(to)) { href = `${URL}${to}`; } history[replace ? 'replace' : 'push'](href); }; const Link = ({ theme, blank, nofollow, download, className, type, auto, external, to, style, children, onPress, replace, wrapper, fontFamily, hrefAttrs }) => { const history = useHistory(); const { location } = history; const amp = useAmp(); if (onPress === null && to === null) { throw new Error('Either `onPress` or `to` must be provided'); } let href = to; if (amp && !href) { href = `${location.pathname}${location.search}${location.hash}`.replace(/^\/amp(\/)?/, '$1').replace(/\/amp\/?$/, ''); if (!href || href[0] !== '/') { href = `/${href}`; } } const Wrapper = wrapper; const currentStyle = [styles.defaults, !auto ? styles.fullWidth : null, typeof children !== 'string' ? styles.noLineHeight : null, theme.colors[type] && theme.colors[type].text, style]; const font = {}; const classNameProp = {}; if (Wrapper === Text) { classNameProp['data-class'] = `${className} ${type}`; classNameProp.dataSet = { class: `${className} ${type}` }; const css = StyleSheet.flatten(currentStyle); if (css.fontWeight === 'bold' && (!css.fontFamily || css.fontFamily === fontFamily.regular)) { font.fontFamily = fontFamily.bold; } else if (!css.fontFamily) { font.fontFamily = fontFamily.regular; } } else { classNameProp.className = `${className} ${type}`; } if (font.fontFamily === 'system font') { delete font.fontFamily; } let adjustedHrefAttrs = hrefAttrs || null; if (blank || nofollow || download) { adjustedHrefAttrs = { target: blank ? 'blank' : null, rel: nofollow ? 'nofollow' : null, download, ...hrefAttrs }; } const wrappedOnPress = amp || blank ? undefined : onPress || go({ to, history, external, replace }); return /*#__PURE__*/React.createElement(Wrapper, _extends({}, classNameProp, { hrefAttrs: adjustedHrefAttrs, href: href, onPress: wrappedOnPress, style: [currentStyle, font], accessibilityRole: "link" }), children); }; Link.propTypes = { theme: PropTypes.shape().isRequired, fontFamily: PropTypes.shape().isRequired, external: PropTypes.bool, auto: PropTypes.bool, type: PropTypes.string, children: PropTypes.node, style: StylePropType, blank: PropTypes.bool, nofollow: PropTypes.bool, download: PropTypes.bool, className: PropTypes.string, to: PropTypes.string, onPress: PropTypes.func, replace: PropTypes.bool, wrapper: PropTypes.any, // eslint-disable-line hrefAttrs: PropTypes.shape() }; Link.defaultProps = { external: false, auto: false, children: null, style: styles.empty, blank: false, nofollow: false, download: undefined, type: 'gray', className: '', to: null, onPress: null, replace: false, wrapper: Text, hrefAttrs: undefined }; export default withTheme('Link')(Link);