This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
import React from 'react';
import type { Locale } from '../locale';
import type { QRCodeProps, StatusRenderInfo } from './interface';
export type QRcodeStatusProps = {
prefixCls: string;
locale?: Locale['QRCode'];
onRefresh?: QRCodeProps['onRefresh'];
statusRender?: QRCodeProps['statusRender'];
status: StatusRenderInfo['status'];
};
export default function QRcodeStatus({ prefixCls, locale, onRefresh, statusRender, status, }: QRcodeStatusProps): React.ReactNode;
+37
View File
@@ -0,0 +1,37 @@
"use client";
import React from 'react';
import ReloadOutlined from "@ant-design/icons/es/icons/ReloadOutlined";
import Button from '../button/Button';
import Spin from '../spin';
const defaultSpin = /*#__PURE__*/React.createElement(Spin, null);
export default function QRcodeStatus({
prefixCls,
locale,
onRefresh,
statusRender,
status
}) {
const defaultExpiredNode = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
className: `${prefixCls}-expired`
}, locale?.expired), onRefresh && (/*#__PURE__*/React.createElement(Button, {
type: "link",
icon: /*#__PURE__*/React.createElement(ReloadOutlined, null),
onClick: onRefresh
}, locale?.refresh)));
const defaultScannedNode = /*#__PURE__*/React.createElement("p", {
className: `${prefixCls}-scanned`
}, locale?.scanned);
const defaultNodes = {
expired: defaultExpiredNode,
loading: defaultSpin,
scanned: defaultScannedNode
};
const defaultStatusRender = info => defaultNodes[info.status];
const mergedStatusRender = statusRender ?? defaultStatusRender;
return mergedStatusRender({
status,
locale,
onRefresh
});
}
+5
View File
@@ -0,0 +1,5 @@
import React from 'react';
import type { QRCodeProps, QRCodeSemanticClassNames, QRCodeSemanticName, QRCodeSemanticStyles, QRProps, QRPropsCanvas, QRPropsSvg } from './interface';
export type { QRCodeProps, QRCodeSemanticClassNames, QRCodeSemanticName, QRCodeSemanticStyles, QRProps, QRPropsCanvas, QRPropsSvg, };
declare const QRCode: React.FC<QRCodeProps>;
export default QRCode;
+131
View File
@@ -0,0 +1,131 @@
"use client";
import React from 'react';
import { QRCodeCanvas, QRCodeSVG } from '@rc-component/qrcode';
import { omit } from '@rc-component/util';
import pickAttrs from "@rc-component/util/es/pickAttrs";
import { clsx } from 'clsx';
import { useMergeSemantic } from '../_util/hooks';
import { isNumber } from '../_util/is';
import { devUseWarning } from '../_util/warning';
import { useComponentConfig } from '../config-provider/context';
import { useLocale } from '../locale';
import { useToken } from '../theme/internal';
import QRcodeStatus from './QrcodeStatus';
import useStyle from './style/index';
const QRCode = props => {
const [, token] = useToken();
const {
value,
type = 'canvas',
icon = '',
size = 160,
iconSize,
color = token.colorText,
errorLevel = 'M',
status = 'active',
bordered = true,
onRefresh,
style,
className,
rootClassName,
prefixCls: customizePrefixCls,
bgColor = 'transparent',
marginSize,
statusRender,
classNames,
styles,
boostLevel /* 👈 5.28.0+ */,
...rest
} = props;
const {
getPrefixCls,
className: contextClassName,
style: contextStyle,
classNames: contextClassNames,
styles: contextStyles
} = useComponentConfig('qrcode');
// =========== Merged Props for Semantic ===========
const mergedProps = {
...props,
bgColor,
type,
size,
status,
bordered,
errorLevel
};
const [mergedClassNames, mergedStyles] = useMergeSemantic([contextClassNames, classNames], [contextStyles, styles], {
props: mergedProps
});
const prefixCls = getPrefixCls('qrcode', customizePrefixCls);
const [hashId, cssVarCls] = useStyle(prefixCls);
const imageSettings = {
src: icon,
x: undefined,
y: undefined,
height: isNumber(iconSize) ? iconSize : iconSize?.height ?? 40,
width: isNumber(iconSize) ? iconSize : iconSize?.width ?? 40,
excavate: true,
crossOrigin: 'anonymous'
};
const a11yProps = pickAttrs(rest, true);
const restProps = omit(rest, Object.keys(a11yProps));
const qrCodeProps = {
value,
size,
level: errorLevel,
bgColor,
fgColor: color,
style: {
width: style?.width,
height: style?.height
},
imageSettings: icon ? imageSettings : undefined,
marginSize,
boostLevel,
...a11yProps
};
const [locale] = useLocale('QRCode');
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('QRCode');
process.env.NODE_ENV !== "production" ? warning(!!value, 'usage', 'need to receive `value` props') : void 0;
process.env.NODE_ENV !== "production" ? warning(!(icon && errorLevel === 'L'), 'usage', 'ErrorLevel `L` is not recommended to be used with `icon`, for scanning result would be affected by low level.') : void 0;
}
if (!value) {
return null;
}
const rootClassNames = clsx(prefixCls, className, rootClassName, hashId, cssVarCls, contextClassName, mergedClassNames.root, {
[`${prefixCls}-borderless`]: !bordered
});
const rootStyle = {
backgroundColor: bgColor,
...mergedStyles.root,
...contextStyle,
...style,
width: style?.width ?? size,
height: style?.height ?? size
};
return /*#__PURE__*/React.createElement("div", {
...restProps,
className: rootClassNames,
style: rootStyle
}, status !== 'active' && (/*#__PURE__*/React.createElement("div", {
className: clsx(`${prefixCls}-cover`, mergedClassNames.cover),
style: mergedStyles.cover
}, /*#__PURE__*/React.createElement(QRcodeStatus, {
prefixCls: prefixCls,
locale: locale,
status: status,
onRefresh: onRefresh,
statusRender: statusRender
}))), type === 'canvas' ? /*#__PURE__*/React.createElement(QRCodeCanvas, {
...qrCodeProps
}) : /*#__PURE__*/React.createElement(QRCodeSVG, {
...qrCodeProps
}));
};
if (process.env.NODE_ENV !== 'production') {
QRCode.displayName = 'QRCode';
}
export default QRCode;
+43
View File
@@ -0,0 +1,43 @@
import type { ReactNode } from 'react';
import type { QRProps } from '@rc-component/qrcode';
import type { SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import type { Locale } from '../locale';
type ImageSettings = QRProps['imageSettings'];
export type { ImageSettings, QRProps };
export type QRPropsCanvas = QRProps & React.CanvasHTMLAttributes<HTMLCanvasElement>;
export type QRPropsSvg = QRProps & React.SVGAttributes<SVGSVGElement>;
export type QRStatus = 'active' | 'expired' | 'loading' | 'scanned';
export type StatusRenderInfo = {
status: Exclude<QRStatus, 'active'>;
locale: Locale['QRCode'];
onRefresh?: () => void;
};
export type QRCodeSemanticName = keyof QRCodeSemanticClassNames & keyof QRCodeSemanticStyles;
export type QRCodeSemanticClassNames = {
root?: string;
cover?: string;
};
export type QRCodeSemanticStyles = {
root?: React.CSSProperties;
cover?: React.CSSProperties;
};
export type QRCodeClassNamesType = SemanticClassNamesType<QRCodeProps, QRCodeSemanticClassNames>;
export type QRCodeStylesType = SemanticStylesType<QRCodeProps, QRCodeSemanticStyles>;
export interface QRCodeProps extends QRProps, React.HTMLAttributes<HTMLDivElement> {
type?: 'canvas' | 'svg';
className?: string;
rootClassName?: string;
prefixCls?: string;
icon?: string;
iconSize?: number | {
width: number;
height: number;
};
bordered?: boolean;
errorLevel?: 'L' | 'M' | 'Q' | 'H';
status?: QRStatus;
onRefresh?: () => void;
statusRender?: (info: StatusRenderInfo) => ReactNode;
classNames?: QRCodeClassNamesType;
styles?: QRCodeStylesType;
}
+1
View File
@@ -0,0 +1 @@
export {};
+6
View File
@@ -0,0 +1,6 @@
import type { GetDefaultToken } from '../../theme/internal';
export interface ComponentToken {
}
export declare const prepareComponentToken: GetDefaultToken<'QRCode'>;
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+68
View File
@@ -0,0 +1,68 @@
import { unit } from '@ant-design/cssinjs';
import { FastColor } from '@ant-design/fast-color';
import { resetComponent } from '../../style';
import { genStyleHooks, mergeToken } from '../../theme/internal';
const genQRCodeStyle = token => {
const {
componentCls,
lineWidth,
lineType,
colorSplit
} = token;
return {
[componentCls]: {
...resetComponent(token),
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: token.paddingSM,
backgroundColor: token.colorWhite,
borderRadius: token.borderRadiusLG,
border: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
position: 'relative',
overflow: 'hidden',
[`& > ${componentCls}-cover`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineStart: 0,
zIndex: 10,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
color: token.colorText,
lineHeight: token.lineHeight,
background: token.QRCodeCoverBackgroundColor,
textAlign: 'center',
[`& > ${componentCls}-expired, & > ${componentCls}-scanned`]: {
color: token.QRCodeTextColor
}
},
'> canvas': {
alignSelf: 'stretch',
flex: 'auto',
minWidth: 0
},
'&-icon': {
marginBlockEnd: token.marginXS,
fontSize: token.controlHeight
}
},
[`${componentCls}-borderless`]: {
borderColor: 'transparent',
padding: 0,
borderRadius: 0
}
};
};
export const prepareComponentToken = token => ({
QRCodeCoverBackgroundColor: new FastColor(token.colorBgContainer).setA(0.96).toRgbString()
});
export default genStyleHooks('QRCode', token => {
const mergedToken = mergeToken(token, {
QRCodeTextColor: token.colorText
});
return genQRCodeStyle(mergedToken);
}, prepareComponentToken);