diff --git a/src/components/QRShare/QRShareWithDownload/index.js b/src/components/QRShare/QRShareWithDownload/index.js
index 688ec15040ac..bf18a8eedaa4 100644
--- a/src/components/QRShare/QRShareWithDownload/index.js
+++ b/src/components/QRShare/QRShareWithDownload/index.js
@@ -1,43 +1,53 @@
-import React, {Component} from 'react';
-import {withNetwork} from '@components/OnyxProvider';
+import React, {forwardRef, useImperativeHandle, useRef} from 'react';
import getQrCodeFileName from '@components/QRShare/getQrCodeDownloadFileName';
import {qrShareDefaultProps, qrSharePropTypes} from '@components/QRShare/propTypes';
+import useNetwork from '@hooks/useNetwork';
import fileDownload from '@libs/fileDownload';
import QRShare from '..';
-class QRShareWithDownload extends Component {
- qrShareRef = React.createRef();
-
- constructor(props) {
- super(props);
-
- this.download = this.download.bind(this);
- }
-
- download() {
- return new Promise((resolve, reject) => {
- // eslint-disable-next-line es/no-optional-chaining
- const svg = this.qrShareRef.current?.getSvg();
- if (svg == null) {
- return reject();
- }
-
- svg.toDataURL((dataURL) => resolve(fileDownload(dataURL, getQrCodeFileName(this.props.title))));
- });
- }
-
- render() {
- return (
-
- );
- }
+function QRShareWithDownload({innerRef, ...props}) {
+ const {isOffline} = useNetwork();
+ const qrShareRef = useRef(null);
+
+ useImperativeHandle(
+ innerRef,
+ () => ({
+ download: () =>
+ new Promise((resolve, reject) => {
+ // eslint-disable-next-line es/no-optional-chaining
+ const svg = qrShareRef.current?.getSvg();
+ if (svg == null) {
+ return reject();
+ }
+
+ svg.toDataURL((dataURL) => resolve(fileDownload(dataURL, getQrCodeFileName(props.title))));
+ }),
+ }),
+ [props.title],
+ );
+
+ return (
+
+ );
}
+
QRShareWithDownload.propTypes = qrSharePropTypes;
QRShareWithDownload.defaultProps = qrShareDefaultProps;
+QRShareWithDownload.displayName = 'QRShareWithDownload';
+
+const QRShareWithDownloadWithRef = forwardRef((props, ref) => (
+
+));
+
+QRShareWithDownloadWithRef.displayName = 'QRShareWithDownloadWithRef';
-export default withNetwork()(QRShareWithDownload);
+export default QRShareWithDownloadWithRef;
diff --git a/src/components/QRShare/QRShareWithDownload/index.native.js b/src/components/QRShare/QRShareWithDownload/index.native.js
index bf67b0955812..e64c7b69df4a 100644
--- a/src/components/QRShare/QRShareWithDownload/index.native.js
+++ b/src/components/QRShare/QRShareWithDownload/index.native.js
@@ -1,37 +1,46 @@
-import React, {Component} from 'react';
+import React, {forwardRef, useImperativeHandle, useRef} from 'react';
import ViewShot from 'react-native-view-shot';
-import {withNetwork} from '@components/OnyxProvider';
import getQrCodeFileName from '@components/QRShare/getQrCodeDownloadFileName';
import {qrShareDefaultProps, qrSharePropTypes} from '@components/QRShare/propTypes';
+import useNetwork from '@hooks/useNetwork';
import fileDownload from '@libs/fileDownload';
import QRShare from '..';
-class QRShareWithDownload extends Component {
- qrCodeScreenshotRef = React.createRef();
+function QRShareWithDownload({innerRef, ...props}) {
+ const {isOffline} = useNetwork();
+ const qrCodeScreenshotRef = useRef(null);
- constructor(props) {
- super(props);
+ useImperativeHandle(
+ innerRef,
+ () => ({
+ download: () => qrCodeScreenshotRef.current.capture().then((uri) => fileDownload(uri, getQrCodeFileName(props.title))),
+ }),
+ [props.title],
+ );
- this.download = this.download.bind(this);
- }
-
- download() {
- return this.qrCodeScreenshotRef.current.capture().then((uri) => fileDownload(uri, getQrCodeFileName(this.props.title)));
- }
-
- render() {
- return (
-
-
-
- );
- }
+ return (
+
+
+
+ );
}
+
QRShareWithDownload.propTypes = qrSharePropTypes;
QRShareWithDownload.defaultProps = qrShareDefaultProps;
+QRShareWithDownload.displayName = 'QRShareWithDownload';
+
+const QRShareWithDownloadWithRef = forwardRef((props, ref) => (
+
+));
+
+QRShareWithDownloadWithRef.displayName = 'QRShareWithDownloadWithRef';
-export default withNetwork()(QRShareWithDownload);
+export default QRShareWithDownloadWithRef;
diff --git a/src/components/QRShare/index.js b/src/components/QRShare/index.js
index be242cdb184f..f7bb5cb5f788 100644
--- a/src/components/QRShare/index.js
+++ b/src/components/QRShare/index.js
@@ -1,96 +1,91 @@
-import React, {Component} from 'react';
+import React, {forwardRef, useImperativeHandle, useRef, useState} from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import ExpensifyWordmark from '@assets/images/expensify-wordmark.svg';
import QRCode from '@components/QRCode';
import Text from '@components/Text';
-import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
-import withTheme, {withThemePropTypes} from '@components/withTheme';
-import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles';
-import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions';
-import compose from '@libs/compose';
+import useTheme from '@styles/themes/useTheme';
+import useThemeStyles from '@styles/useThemeStyles';
import variables from '@styles/variables';
import {qrShareDefaultProps, qrSharePropTypes} from './propTypes';
-const propTypes = {
- ...qrSharePropTypes,
- ...windowDimensionsPropTypes,
- ...withLocalizePropTypes,
- ...withThemeStylesPropTypes,
- ...withThemePropTypes,
-};
+function QRShare({innerRef, url, title, subtitle, logo, logoRatio, logoMarginRatio}) {
+ const styles = useThemeStyles();
+ const theme = useTheme();
-class QRShare extends Component {
- constructor(props) {
- super(props);
+ const [qrCodeSize, setQrCodeSize] = useState(1);
+ const svgRef = useRef(null);
- this.state = {
- qrCodeSize: 1,
- };
+ useImperativeHandle(
+ innerRef,
+ () => ({
+ getSvg: () => svgRef.current,
+ }),
+ [],
+ );
- this.onLayout = this.onLayout.bind(this);
- this.getSvg = this.getSvg.bind(this);
- }
-
- onLayout(event) {
+ const onLayout = (event) => {
const containerWidth = event.nativeEvent.layout.width - variables.qrShareHorizontalPadding * 2 || 0;
+ setQrCodeSize(Math.max(1, containerWidth));
+ };
- this.setState({
- qrCodeSize: Math.max(1, containerWidth),
- });
- }
+ return (
+
+
+
+
- getSvg() {
- return this.svg;
- }
+ (svgRef.current = svg)}
+ url={url}
+ logo={logo}
+ size={qrCodeSize}
+ logoRatio={logoRatio}
+ logoMarginRatio={logoMarginRatio}
+ />
- render() {
- return (
-
-
-
-
-
- (this.svg = svg)}
- url={this.props.url}
- logo={this.props.logo}
- size={this.state.qrCodeSize}
- logoRatio={this.props.logoRatio}
- logoMarginRatio={this.props.logoMarginRatio}
- />
+ {title}
+
+ {!_.isEmpty(subtitle) && (
- {this.props.title}
+ {subtitle}
-
- {!_.isEmpty(this.props.subtitle) && (
-
- {this.props.subtitle}
-
- )}
-
- );
- }
+ )}
+
+ );
}
-QRShare.propTypes = propTypes;
+
+QRShare.propTypes = qrSharePropTypes;
QRShare.defaultProps = qrShareDefaultProps;
+QRShare.displayName = 'QRShare';
+
+const QRShareWithRef = forwardRef((props, ref) => (
+
+));
+
+QRShareWithRef.displayName = 'QRShareWithRef';
-export default compose(withLocalize, withWindowDimensions, withThemeStyles, withTheme)(QRShare);
+export default QRShareWithRef;
diff --git a/src/components/QRShare/propTypes.js b/src/components/QRShare/propTypes.js
index 69a9fcce2938..28275bc724b1 100644
--- a/src/components/QRShare/propTypes.js
+++ b/src/components/QRShare/propTypes.js
@@ -5,31 +5,41 @@ const qrSharePropTypes = {
* The QR code URL
*/
url: PropTypes.string.isRequired,
+
/**
* The title that is displayed below the QR Code (usually the user or report name)
*/
title: PropTypes.string.isRequired,
+
/**
* The subtitle which will be shown below the title (usually user email or workspace name)
* */
subtitle: PropTypes.string,
+
/**
* The logo which will be display in the middle of the QR code
*/
logo: PropTypes.oneOfType([PropTypes.shape({uri: PropTypes.string}), PropTypes.number, PropTypes.string]),
+
/**
* The size ratio of logo to QR code
*/
logoRatio: PropTypes.number,
+
/**
* The size ratio of margin around logo to QR code
*/
logoMarginRatio: PropTypes.number,
+
+ /**
+ * Forwarded ref
+ */
+ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
};
-const defaultProps = {
+const qrShareDefaultProps = {
subtitle: undefined,
logo: undefined,
};
-export {qrSharePropTypes, defaultProps as qrShareDefaultProps};
+export {qrSharePropTypes, qrShareDefaultProps};