react-native-qrcode-styled
Version:
A fully customizable QR Code generator for React Native based on react-native-svg and javascript-qrcode.
167 lines (166 loc) • 5.77 kB
JavaScript
"use strict";
import React, { forwardRef, useEffect, useMemo, useState } from 'react';
import { Svg, Defs, G, ClipPath, Image as SVGImage } from 'react-native-svg';
import { transformEyeOptionsToCommonPattern } from "../helpers.js";
import { INNER_EYE_SIZE_IN_BITS, OUTER_EYE_SIZE_IN_BITS } from "../constants.js";
import useQRCodeData from "../hooks/useQRCodeData.js";
import SVGPieces, { DEFAULT_PIECE_SIZE } from "./SVGPieces.js";
import SVGQRLogo from "./SVGQRLogo.js";
import SVGGradient from "./SVGGradient.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
function SVGQRCodeStyled({
data = "I'm QR Code!",
onChangeSize,
pieceSize = DEFAULT_PIECE_SIZE,
pieceScale,
pieceRotation,
pieceCornerType = 'rounded',
pieceBorderRadius = 0,
pieceStroke,
pieceStrokeWidth,
pieceLiquidRadius,
isPiecesGlued = false,
outerEyesOptions,
innerEyesOptions,
renderCustomPieceItem,
padding,
color = 'black',
gradient,
logo,
backgroundImage,
version,
maskPattern,
toSJISFunc,
errorCorrectionLevel = 'M',
children,
renderBackground,
...props
}, ref) {
const {
hidePieces = true,
onChange: onChangeLogo,
...logoProps
} = logo || {};
const [logoArea, setLogoArea] = useState();
const qrCodeOptions = useMemo(() => ({
version,
errorCorrectionLevel,
maskPattern,
toSJISFunc
}), [errorCorrectionLevel, maskPattern, toSJISFunc, version]);
const {
qrCodeSize,
bitMatrix
} = useQRCodeData(data, qrCodeOptions);
const svgSize = pieceSize * qrCodeSize;
useEffect(() => {
onChangeSize?.(qrCodeSize);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [qrCodeSize]);
const transformedOuterEyesOptions = transformEyeOptionsToCommonPattern(outerEyesOptions);
const transformedInnerEyesOptions = transformEyeOptionsToCommonPattern(innerEyesOptions);
const _props = {
...props
};
if (padding) {
const _size = svgSize + 2 * padding;
_props.width = _size;
_props.height = _size;
_props.viewBox = `-${padding} -${padding} ${_size} ${_size}`;
}
const startGradientOuterEyeCoords = {
topLeft: [0, 0],
topRight: [svgSize - pieceSize * OUTER_EYE_SIZE_IN_BITS, 0],
bottomLeft: [0, svgSize - pieceSize * OUTER_EYE_SIZE_IN_BITS]
};
const startGradientInnerEyeCoords = {
topLeft: [2 * pieceSize, 2 * pieceSize],
topRight: [svgSize - pieceSize * INNER_EYE_SIZE_IN_BITS + 2 * pieceSize, 2 * pieceSize],
bottomLeft: [2 * pieceSize, svgSize - pieceSize * OUTER_EYE_SIZE_IN_BITS + 2 * pieceSize]
};
const renderPieces = () => /*#__PURE__*/_jsx(SVGPieces, {
bitMatrix: bitMatrix,
isPiecesGlued: isPiecesGlued,
pieceLiquidRadius: pieceLiquidRadius,
pieceBorderRadius: pieceBorderRadius,
pieceCornerType: pieceCornerType,
pieceRotation: pieceRotation,
pieceScale: pieceScale,
pieceSize: pieceSize,
pieceStroke: pieceStroke,
pieceStrokeWidth: pieceStrokeWidth,
outerEyesOptions: transformedOuterEyesOptions,
innerEyesOptions: transformedInnerEyesOptions,
renderCustomPieceItem: renderCustomPieceItem,
logoArea: hidePieces ? logoArea : undefined
});
const handleChangeLogo = area => {
setLogoArea(area);
onChangeLogo?.(area);
};
const renderLogo = () => logo ? /*#__PURE__*/_jsx(SVGQRLogo, {
...logoProps,
errorCorrectionLevel: errorCorrectionLevel,
pieceSize: pieceSize,
qrCodeSize: qrCodeSize,
onChange: handleChangeLogo
}) : null;
if (backgroundImage) {
return /*#__PURE__*/_jsxs(Svg, {
ref: ref,
width: svgSize,
height: svgSize,
..._props,
children: [/*#__PURE__*/_jsx(Defs, {
children: /*#__PURE__*/_jsx(ClipPath, {
id: 'image',
children: /*#__PURE__*/_jsx(G, {
children: renderPieces()
})
})
}), renderBackground?.(pieceSize, bitMatrix), /*#__PURE__*/_jsx(SVGImage, {
x: "0",
y: "0",
width: "100%",
height: "100%",
preserveAspectRatio: "xMaxYMax slice",
...backgroundImage,
clipPath: "url(#image)"
}), renderLogo(), children?.(pieceSize, bitMatrix)]
});
}
return /*#__PURE__*/_jsxs(Svg, {
ref: ref,
width: svgSize,
height: svgSize,
..._props,
children: [(!!gradient || !!transformedOuterEyesOptions || !!transformedInnerEyesOptions) && /*#__PURE__*/_jsxs(Defs, {
children: [!!gradient && /*#__PURE__*/_jsx(SVGGradient, {
id: "gradient",
size: svgSize,
...gradient
}), !!transformedOuterEyesOptions && Object.keys(transformedOuterEyesOptions).map(key => {
return /*#__PURE__*/_jsx(SVGGradient, {
id: `${key}CornerSquareGradient`,
size: pieceSize * OUTER_EYE_SIZE_IN_BITS,
origin: startGradientOuterEyeCoords[key],
...transformedOuterEyesOptions?.[key]?.gradient
}, `${key}CornerSquareGradient`);
}), !!transformedInnerEyesOptions && Object.keys(transformedInnerEyesOptions).map(key => {
return /*#__PURE__*/_jsx(SVGGradient, {
id: `${key}CornerDotGradient`,
size: pieceSize * INNER_EYE_SIZE_IN_BITS,
origin: startGradientInnerEyeCoords[key],
...transformedInnerEyesOptions?.[key]?.gradient
}, `${key}CornerDotGradient`);
})]
}), renderBackground?.(pieceSize, bitMatrix), /*#__PURE__*/_jsx(G, {
fill: gradient ? 'url(#gradient)' : color,
children: renderPieces()
}), renderLogo(), children?.(pieceSize, bitMatrix)]
});
}
const forwardedSVGQRCodeStyled = /*#__PURE__*/forwardRef(SVGQRCodeStyled);
forwardedSVGQRCodeStyled.displayName = 'SVGQRCodeStyled';
export default forwardedSVGQRCodeStyled;
//# sourceMappingURL=SVGQRCodeStyled.js.map