feat(@zhst/meta): 初始化

This commit is contained in:
NICE CODE BY DEV 2024-01-16 17:35:23 +08:00
parent 1260619b42
commit 355354a96d
1267 changed files with 718355 additions and 2208 deletions

6
.dumi/global.less Normal file
View File

@ -0,0 +1,6 @@
#root .dumi-default-doc-layout .dumi-default-features-item {
text-align: center;
}
#root .dumi-default-doc-layout > main {
max-width: none;
}

View File

@ -2,3 +2,5 @@
*.yaml
/docs-dist
/packages
packages/*/*.js
packages/*/*.jsx

View File

@ -5,6 +5,7 @@
"COMPATER",
"favicons",
"flvjs",
"indicatorsize",
"lambo",
"remuxer",
"transmuxer",

View File

@ -1,5 +1,12 @@
# @zhst/biz
## 0.3.2
### Patch Changes
- Updated dependencies
- @zhst/meta@0.4.0
## 0.3.1
### Patch Changes

View File

@ -1,6 +1,6 @@
{
"name": "@zhst/biz",
"version": "0.3.1",
"version": "0.3.2",
"description": "业务库",
"keywords": [
"business",

View File

@ -1,5 +1,13 @@
# @zhst/biz
## 0.3.2
### Patch Changes
- Updated dependencies
- @zhst/meta@0.4.0
- @zhst/biz@0.3.2
## 0.3.1
### Patch Changes

View File

@ -1,6 +1,6 @@
{
"name": "@zhst/material",
"version": "0.3.1",
"version": "0.3.2",
"description": "物料库",
"keywords": [
"business",

View File

@ -1,5 +1,11 @@
# @zhst/utils
## 0.4.0
### Minor Changes
- feat: 初始化 meta 仓库
## 0.3.1
### Patch Changes

View File

@ -1,35 +0,0 @@
import React, { ReactElement } from 'react';
import { type Rect, type IScreenshotButtonProp, type AlignType, type ViewOption, type IOdRectOrigin } from '@zhst/types';
import './index.less';
export interface ImgViewProps extends React.HTMLAttributes<HTMLElement> {
dataSource: Array<{
url?: string;
imageKey: string;
attachImg?: Array<{
label: string;
url: string;
}>;
odRect?: Rect;
score?: number;
showScore?: boolean;
cameraPosition?: string;
time?: string | number;
objects: any[];
}>;
showAttachImgLabel: boolean;
showOpt: boolean;
width?: string | number;
height?: string | number;
screenshotButtonAlign: AlignType;
screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
hideLeftTopBtn?: boolean;
showScore?: boolean;
viewOption?: ViewOption;
objects: IOdRectOrigin[];
}
export interface ImgViewRef {
imgInsRef: React.MutableRefObject<any>;
setShowCrop: React.Dispatch<React.SetStateAction<boolean>>;
}
export declare const BigImagePreview: React.ForwardRefExoticComponent<ImgViewProps & React.RefAttributes<ImgViewRef>>;
export default BigImagePreview;

View File

@ -1,17 +0,0 @@
import React, { MouseEvent } from 'react';
import { TooltipProps } from 'antd';
import './index.less';
export interface BtnGroupProps {
className: string;
dataSource: Array<{
key: string;
icon: string;
title: string;
}>;
onClick: (v: string, e: MouseEvent<HTMLElement>) => void;
selectKey?: string;
circle?: boolean;
placement?: TooltipProps['placement'];
}
export declare const BtnGroup: React.FC<BtnGroupProps>;
export default BtnGroup;

View File

@ -1,14 +0,0 @@
import React from 'react';
import type { AlgorithmVersion } from '@zhst/types';
import './index.less';
interface IScreenShotButton {
getCropInfo: () => void;
setShowCrop: any;
cropType: string;
selectAlgorithmVersion?: AlgorithmVersion | null;
}
declare const getScreenshotButtonRender: (arg: {
disableBtn: number[];
onBigImageActionClick: (type: number, item: any) => void;
}) => (param: IScreenShotButton) => React.JSX.Element;
export default getScreenshotButtonRender;

View File

@ -1,3 +0,0 @@
import BigImagePreview from './BigImagePreview';
export type { ImgViewProps } from './BigImagePreview';
export default BigImagePreview;

View File

@ -62,9 +62,14 @@
height: 202px;
transition: all 200ms;
&--fixed {
}
&--zoomin {
height: 100%;
&--fixed {
}
}
&__tab {

View File

@ -1,20 +0,0 @@
import React from 'react';
import './index.less';
export interface CompareImageProps {
/**
* @description
* @default "默认值"
*/
label: string;
openRoll?: boolean;
dataSource?: Array<{
url: string;
score: number;
}>;
showScore?: boolean;
current: number;
}
export interface CompareImageRefProps {
}
declare const CompareImage: React.ForwardRefExoticComponent<CompareImageProps & React.RefAttributes<CompareImageRefProps>>;
export default CompareImage;

View File

@ -1,7 +0,0 @@
import React from 'react';
import './index.less';
export interface ScoreProps {
scoreTxt: number;
}
export declare const CornerScore: React.FC<ScoreProps>;
export default CornerScore;

View File

@ -1,3 +0,0 @@
import CompareImage from "./CompareImage";
export type { CompareImageProps } from './CompareImage';
export default CompareImage;

View File

@ -1,26 +0,0 @@
export declare const NAMESPACE = "zhst-cropper";
export declare const ACTION_MOVE = "move";
export declare const ACTION_CROP = "crop";
export declare const ACTION_EAST = "e";
export declare const ACTION_WEST = "w";
export declare const ACTION_SOUTH = "s";
export declare const ACTION_NORTH = "n";
export declare const ACTION_NORTH_EAST = "ne";
export declare const ACTION_NORTH_WEST = "nw";
export declare const ACTION_SOUTH_EAST = "se";
export declare const ACTION_SOUTH_WEST = "sw";
export declare const CLASS_HIDDEN: string;
export declare const CLASS_MASK: string;
export declare const DATA_ACTION: string;
export declare const EVENT_TOUCH_START: string;
export declare const EVENT_TOUCH_MOVE: string;
export declare const EVENT_TOUCH_END: string;
export declare const EVENT_POINTER_DOWN: string;
export declare const EVENT_POINTER_MOVE: string;
export declare const EVENT_POINTER_UP: string;
export declare const EVENT_WHEEL = "wheel";
export declare const EVENT_CROP_CHANGE = "crop-change";
export declare const EVENT_CROP_START = "crop-start";
export declare const EVENT_CROP_END = "crop-end";
export declare const REGEXP_SPACES: RegExp;
export declare const REGEXP_ACTIONS: RegExp;

View File

@ -1,9 +0,0 @@
declare const _default: {
bind(): void;
unbind(): void;
onCropStart(event: any): void;
onCropMove(event: any): void;
onCropEnd(event: any): void;
change(event: any): void;
};
export default _default;

View File

@ -1,34 +0,0 @@
import './index.module.scss';
export interface Option {
image?: string | HTMLImageElement;
showMask?: boolean;
cropBoxLimited?: {
width: number;
height: number;
top: number;
left: number;
};
minCropBoxWidth?: number;
minCropBoxHeight?: number;
viewer?: any;
initialCropBoxData?: any;
}
declare class Cropper {
element: HTMLDivElement;
options: Option;
cropped: boolean;
limited: boolean;
image: HTMLImageElement;
eventHandleList: never[];
container: Element;
dragBox: Element;
cropBox: Element;
viewBox: Element;
constructor(element: any, options?: any);
init(): Promise<void>;
initDefaultCropBox(): void;
load(): Promise<HTMLElement>;
build(): void;
destroy(): void;
}
export default Cropper;

View File

@ -1,6 +0,0 @@
declare const _default: {
previewBox: null;
initPreview(): void;
renderPreview(): void;
};
export default _default;

View File

@ -1,20 +0,0 @@
declare const _default: {
cropBoxData: null;
viewBoxImage: null;
render(): void;
initContainer(): void;
initCropBox(): void;
renderCropBox(): void;
clearCropBox(): {
cropBoxData: null;
viewBoxImage: null;
render(): void;
initContainer(): void;
initCropBox(): void;
renderCropBox(): void;
clearCropBox(): any;
limitCropBox(sizeLimited: any, positionLimited: any): void;
};
limitCropBox(sizeLimited: any, positionLimited: any): void;
};
export default _default;

View File

@ -1,7 +0,0 @@
declare const _default: {
initBridge(): void;
onTransformChange(viewer: any): void;
onWheel(event: any): void;
clearBridge(): void;
};
export default _default;

View File

@ -1,4 +0,0 @@
export { default as Cropper } from './cropper';
export { default as Viewer } from './viewer';
export { EVENT_CROP_CHANGE, EVENT_CROP_START, EVENT_CROP_END } from './cropper/constants';
export { EVENT_VIEWER_TRANSFORM_CHANGE, EVENT_VIEWER_READY, EVENT_VIEWER_ERROR, EVENT_SHAPE_SELECT, EVENT_EYE_DONE, } from './viewer/constants';

View File

@ -1,89 +0,0 @@
export declare const IS_BROWSER: boolean;
export declare const WINDOW: {};
export declare const IS_TOUCH_DEVICE: boolean;
export declare const HAS_POINTER_EVENT: boolean;
/**
* Transform the given string from camelCase to kebab-case
* @param {string} value - The value to transform.
* @returns {string} The transformed value.
*/
export declare function toParamCase(value: any): any;
/**
* Get data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to get.
* @returns {string} The data value.
*/
export declare function getData(element: any, name: any): any;
export declare function toggleClass(node: HTMLElement, className: string): void;
/**
* Get a pointer from an event object.
* @param {Object} event - The target event object.
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
* @returns {Object} The result pointer contains start and/or end point coordinates.
*/
export declare function getPointer({ pageX, pageY }: {
pageX: any;
pageY: any;
}, endOnly?: any): {
endX: any;
endY: any;
} | {
endX: any;
endY: any;
startX: any;
startY: any;
};
/**
* Get the offset base on the document.
* @param {Element} element - The target element.
* @returns {Object} The offset data.
*/
export declare function getOffset(element: any): {
left: any;
top: any;
};
/**
* Get transforms base on the given object.
* @param {Object} obj - The target object.
* @returns {string} A string contains transform values.
*/
export declare function getTransforms({ rotate, scaleX, scaleY, translateX, translateY, }: {
rotate?: number;
scaleX?: number;
scaleY?: number;
translateX?: number;
translateY?: number;
}): {
WebkitTransform: string;
msTransform: string;
transform: string;
};
/**
* copy from https://github.com/steelsojka/lodash-decorators/blob/master/src/mixin.ts
* Mixins an object into the classes prototype.
* @export
* @param {...Object[]} srcs
* @returns {ClassDecorator}
* @example
*
* const myMixin = {
* blorg: () => 'blorg!'
* }
*
* @Mixin(myMixin)
* class MyClass {}
*
* const myClass = new MyClass();
*
* myClass.blorg(); // => 'blorg!'
*/
export declare function Mixin(...srcs: Object[]): ClassDecorator;
/**
* Dispatch event on the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Object} data - The additional event data.
* @returns {boolean} Indicate if the event is default prevented or not.
*/
export declare function dispatchEvent(element: any, type: any, data?: any): any;

View File

@ -1,26 +0,0 @@
export declare const NAMESPACE = "zhst-viewer";
export declare const ACTION_DRAG = "drag";
export declare const CLASS_CANVAS: string;
export declare const CLASS_MOVE: string;
export declare const EVENT_CLICK = "click";
export declare const EVENT_TOUCH_START: string;
export declare const EVENT_TOUCH_MOVE: string;
export declare const EVENT_TOUCH_END: string;
export declare const EVENT_POINTER_DOWN: string;
export declare const EVENT_POINTER_MOVE: string;
export declare const EVENT_POINTER_UP: string;
export declare const EVENT_WHEEL = "wheel";
export declare const EVENT_LEAVEL = "mouseleave";
export declare const EVENT_ENTER = "mouseenter";
export declare const EVENT_VIEWER_TRANSFORM_CHANGE = "viewer-transform-change";
export declare const EVENT_VIEWER_READY = "viewer-ready";
export declare const EVENT_VIEWER_ERROR = "viewer-error";
export declare const EVENT_SHAPE_SELECT = "shape-select";
export declare const EVENT_EYE_DONE = "eye-done";
export declare const REGEXP_SPACES: RegExp;
export declare const AXIS_TYPE_ORIGIN = 1;
export declare const AXIS_TYPE_CANVAS = 2;
export declare const AXIS_TYPE_IMAGE = 3;
export declare const SHAPE_TYPE_CUSTOM = 1;
export declare const SHAPE_TYPE_RECT = 2;
export declare const SHAPE_TYPE_CIRCLE = 3;

View File

@ -1,15 +0,0 @@
declare const _default: {
disabled: boolean;
eventHandleList: never[];
wheeling: boolean;
pointer: null;
action: null;
bind(): void;
unbind(): void;
onWheel(event: any, cropBox?: any): void;
onDragStart(event: any): void;
onDragMove(event: any): void;
onDragEnd(event: any): void;
onClick(event: any): void;
};
export default _default;

View File

@ -1,43 +0,0 @@
export declare const setNumberAccuracy: (originNumber: number, accuracy?: number, isCeil?: boolean) => number;
declare const _default: {
windowToCanvasAxis(event: any): any;
offsetAxisToCanvasAxis({ x, y }: {
x: any;
y: any;
}): any;
originAxisToCanvasAxis({ x, y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
canvasAxisToOriginAxis({ x, y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
imgRectAxisToCanvasAxisRect({ x, y, w, h, ...others }: {
[x: string]: any;
x?: number | undefined;
y?: number | undefined;
w?: number | undefined;
h?: number | undefined;
}): any;
originAxisToImgAxis({ x, y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
imgAxisToOriginAxis({ x: _x, y: _y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
getDataUrlbyOriginAxis({ x, y, w, h, ...others }: {
[x: string]: any;
x?: number | undefined;
y?: number | undefined;
w?: number | undefined;
h?: number | undefined;
}): string;
};
export default _default;

View File

@ -1,21 +0,0 @@
import './index.scss';
export interface Option {
image?: string | HTMLImageElement;
wheelZoomRatio?: number;
scaleAble?: boolean;
dragAble?: boolean;
fitScaleAsMinScale?: boolean;
}
declare class Viewer {
element: HTMLDivElement;
image: HTMLImageElement;
canvas: Element;
options: Option;
ready: boolean;
constructor(element: any, options: any);
init(): Promise<void>;
build(): void;
refleshImage(options: any): void;
destroy(): void;
}
export default Viewer;

View File

@ -1,35 +0,0 @@
declare const _default: {
image: null;
canvas: null;
containerData: {
width: number;
height: number;
};
animationFrame: null;
backgroundColor: string;
targetTransform: {
translateX: number;
translateY: number;
scale: number;
rotate: number;
};
render(): Promise<void>;
initImg(): Promise<HTMLElement>;
initCanvas(): void;
startRaf(): void;
renderCanvas(_ctx: any): void;
scaleTo(offsetScale: any): void;
rotateTo(T: number | ((preDeg: number) => number)): void;
reset(): void;
getImgSize(): {
w: any;
h: any;
} | undefined;
calcFitScreen(): {
translateX: number;
translateY: number;
scale: number;
} | undefined;
calcTransform(newTransform: any, cropBox: any): void;
};
export default _default;

View File

@ -1,40 +0,0 @@
export interface Shape {
id: number | string;
selectAble: boolean;
color: string;
}
export interface Rect extends Shape {
x: number;
y: number;
w: number;
h: number;
}
export interface Point extends Shape {
x: number;
y: number;
}
declare const _default: {
shapeList: never[];
hoverShapId: null;
selectShapId: null;
isEyeOpen: boolean;
movable: boolean;
zoomable: boolean;
disableAdd: boolean;
color: string;
changeEyeModel(isOpen: any): void;
addShape(shap: Shape | Array<Shape>, type?: number): void;
setSelectShapId(id: number): void;
getSelectShape(contain?: boolean): any[];
replaceShape(shape: Shape | Shape[] | ((shape: Shape) => Shape | Array<Shape>), type?: number): void;
clearShape(): void;
calcSelectShape(canvasPoint: any): null;
clearSelectShape(): void;
changeMoveAble(movable?: boolean): void;
changeZoonAble(zoomable?: boolean): void;
disabledAddShap(value?: boolean): void;
renderShape(ctx: any): void;
renderRect(ctx: any, shape: any, type: any): void;
renderPoint(ctx: any, shape: any): void;
};
export default _default;

View File

@ -1,6 +0,0 @@
import { FC } from 'react';
import type { ButtonProps } from 'antd/lib/button';
interface IButtonDemo extends ButtonProps {
}
declare const ButtonDemo: FC<IButtonDemo>;
export default ButtonDemo;

View File

@ -1,18 +0,0 @@
import React, { Dispatch, ReactElement, SetStateAction } from 'react';
import { Rect, IScreenshotButtonProp, AlignType } from '@zhst/types';
import './index.less';
export interface VideoViewProps {
url: string;
maxDuration?: number;
screenshotButtonAlign?: AlignType;
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
defautlNormalizationRect?: Rect;
onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void;
}
export interface VideoViewRef {
cropAble: boolean;
setShowCrop: Dispatch<SetStateAction<boolean>>;
downloadVideoframe: () => void;
}
declare const VideoPlayer: React.ForwardRefExoticComponent<VideoViewProps & React.RefAttributes<VideoViewRef>>;
export default VideoPlayer;

View File

@ -1,46 +0,0 @@
import React, { Component, CSSProperties } from 'react';
import flvjs from 'flv.js';
export declare const FLV_EVENT: Readonly<flvjs.Events>;
export interface VideoPlayerProps {
className: string;
style?: CSSProperties;
type: string;
isLive?: boolean;
cors?: boolean;
withCredentials?: boolean;
playId?: number;
hasAudio?: boolean;
hasVideo?: boolean;
duration?: number;
filesize?: number;
url?: string;
autoPlay?: boolean;
onCreat?: any;
/**
* @see https://github.com/Bilibili/flv.js/blob/master/docs/api.md#config
*/
config: object;
}
export default class VideoPlayer extends Component<VideoPlayerProps, any> {
state: {
curPlayUrl: string;
shouldReinit: boolean;
};
flvPlayer: any;
videoElement: null;
static getDerivedStateFromProps: (nextProps: {
url?: any;
playId?: any;
}, prevState: {
curPlayUrl?: any;
playId?: any;
}) => {
playId: any;
curPlayUrl: any;
shouldReinit: boolean;
} | null;
initFlv: ($video: null) => void;
componentWillUnmount(): void;
componentDidUpdate(): void;
render(): React.JSX.Element;
}

View File

@ -1,8 +0,0 @@
import { FC } from 'react';
import './index.less';
export interface ILoading {
status: 'LOADING' | 'COMPLETED' | 'END' | 'ERROR' | null;
reload: () => void;
}
declare const Loading: FC<ILoading>;
export default Loading;

View File

@ -1,10 +0,0 @@
import React from 'react';
import type { SliderSingleProps } from 'antd';
import './index.less';
export interface RangeWrapperProps extends SliderSingleProps {
showSlider: boolean;
className?: string;
min: number;
}
export declare const Range: React.FC<RangeWrapperProps>;
export default Range;

View File

@ -1,3 +0,0 @@
import VideoPlayer from './VideoPlayer';
export type { VideoViewProps, VideoViewRef } from './VideoPlayer';
export default VideoPlayer;

View File

@ -1 +0,0 @@
export declare function getShowStatus(isLoadingVideo: boolean, isEnd: boolean, isError: boolean): string | null;

View File

@ -1,5 +0,0 @@
export declare const doubleCheck: (title?: string, option?: any) => {
destroy: () => void;
update: (configUpdate: import("antd").ModalFuncProps | ((prevConfig: import("antd").ModalFuncProps) => import("antd").ModalFuncProps)) => void;
};
export default doubleCheck;

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
import React from 'react';
import './iconfont.css';
interface IconFontProps {
styles?: React.CSSProperties;
icon?: string;
size?: number;
color?: string;
title?: string;
className?: string;
onIconClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
children?: React.ReactNode;
active?: boolean;
disable?: boolean;
}
declare const IconFont: React.FC<IconFontProps>;
export default IconFont;

View File

@ -1,5 +0,0 @@
export { default as doubleClick } from './doubleClick';
export { default as Icon } from './iconfont';
export { default as CompareImage } from './CompareImage';
export { default as BigImagePreview } from './BigImagePreview';
export { default as VideoPlayer } from './VideoPlayer';

View File

@ -2,4 +2,21 @@ export { default as doubleClick } from "./doubleClick";
export { default as Icon } from "./iconfont";
export { default as CompareImage } from "./CompareImage";
export { default as BigImagePreview } from "./BigImagePreview";
export { default as VideoPlayer } from "./VideoPlayer";
export { default as VideoPlayer } from "./VideoPlayer";
export { default as Tabs } from "./tabs";
export { default as Button } from "./button";
export { default as Space } from "./space";
export { default as Switch } from "./switch";
export { default as Grid } from "./grid";
export { default as TimePicker } from "./time-picker";
export { default as DatePicker } from "./date-picker";
export { default as Calender } from "./calendar";
export { default as Empty } from "./empty";
export { default as Form } from "./form";
export { default as Select } from "./select";
export { default as Radio } from "./radio";
export { default as CheckBox } from "./checkbox";
export { default as Input } from "./input";
export { default as ConfigProvider } from "./config-provider";
export { default as Theme } from "./theme";
export { default as Locale } from "./locale";

View File

@ -1,12 +0,0 @@
export declare const CROP_TYPE: {
CUSTOM: string;
AUTO: string;
};
export declare const defaultAlignOption: {
points: string[];
offset: number[];
overflow: {
adjustX: boolean;
adjustY: boolean;
};
};

View File

View File

@ -1,35 +0,0 @@
import React, { ReactElement } from 'react';
import { type Rect, type IScreenshotButtonProp, type AlignType, type ViewOption, type IOdRectOrigin } from '@zhst/types';
import './index.less';
export interface ImgViewProps extends React.HTMLAttributes<HTMLElement> {
dataSource: Array<{
url?: string;
imageKey: string;
attachImg?: Array<{
label: string;
url: string;
}>;
odRect?: Rect;
score?: number;
showScore?: boolean;
cameraPosition?: string;
time?: string | number;
objects: any[];
}>;
showAttachImgLabel: boolean;
showOpt: boolean;
width?: string | number;
height?: string | number;
screenshotButtonAlign: AlignType;
screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
hideLeftTopBtn?: boolean;
showScore?: boolean;
viewOption?: ViewOption;
objects: IOdRectOrigin[];
}
export interface ImgViewRef {
imgInsRef: React.MutableRefObject<any>;
setShowCrop: React.Dispatch<React.SetStateAction<boolean>>;
}
export declare const BigImagePreview: React.ForwardRefExoticComponent<ImgViewProps & React.RefAttributes<ImgViewRef>>;
export default BigImagePreview;

View File

@ -1,17 +0,0 @@
import React, { MouseEvent } from 'react';
import { TooltipProps } from 'antd';
import './index.less';
export interface BtnGroupProps {
className: string;
dataSource: Array<{
key: string;
icon: string;
title: string;
}>;
onClick: (v: string, e: MouseEvent<HTMLElement>) => void;
selectKey?: string;
circle?: boolean;
placement?: TooltipProps['placement'];
}
export declare const BtnGroup: React.FC<BtnGroupProps>;
export default BtnGroup;

View File

@ -1,14 +0,0 @@
import React from 'react';
import type { AlgorithmVersion } from '@zhst/types';
import './index.less';
interface IScreenShotButton {
getCropInfo: () => void;
setShowCrop: any;
cropType: string;
selectAlgorithmVersion?: AlgorithmVersion | null;
}
declare const getScreenshotButtonRender: (arg: {
disableBtn: number[];
onBigImageActionClick: (type: number, item: any) => void;
}) => (param: IScreenShotButton) => React.JSX.Element;
export default getScreenshotButtonRender;

View File

@ -1,3 +0,0 @@
import BigImagePreview from './BigImagePreview';
export type { ImgViewProps } from './BigImagePreview';
export default BigImagePreview;

View File

@ -62,8 +62,14 @@
height: 202px;
transition: all 200ms;
&--fixed {
}
&--zoomin {
height: 100%;
&--fixed {
}
}
&__tab {

View File

@ -1,20 +0,0 @@
import React from 'react';
import './index.less';
export interface CompareImageProps {
/**
* @description
* @default "默认值"
*/
label: string;
openRoll?: boolean;
dataSource?: Array<{
url: string;
score: number;
}>;
showScore?: boolean;
current: number;
}
export interface CompareImageRefProps {
}
declare const CompareImage: React.ForwardRefExoticComponent<CompareImageProps & React.RefAttributes<CompareImageRefProps>>;
export default CompareImage;

View File

@ -1,7 +0,0 @@
import React from 'react';
import './index.less';
export interface ScoreProps {
scoreTxt: number;
}
export declare const CornerScore: React.FC<ScoreProps>;
export default CornerScore;

View File

@ -1,3 +0,0 @@
import CompareImage from "./CompareImage";
export type { CompareImageProps } from './CompareImage';
export default CompareImage;

View File

@ -1,26 +0,0 @@
export declare const NAMESPACE = "zhst-cropper";
export declare const ACTION_MOVE = "move";
export declare const ACTION_CROP = "crop";
export declare const ACTION_EAST = "e";
export declare const ACTION_WEST = "w";
export declare const ACTION_SOUTH = "s";
export declare const ACTION_NORTH = "n";
export declare const ACTION_NORTH_EAST = "ne";
export declare const ACTION_NORTH_WEST = "nw";
export declare const ACTION_SOUTH_EAST = "se";
export declare const ACTION_SOUTH_WEST = "sw";
export declare const CLASS_HIDDEN: string;
export declare const CLASS_MASK: string;
export declare const DATA_ACTION: string;
export declare const EVENT_TOUCH_START: string;
export declare const EVENT_TOUCH_MOVE: string;
export declare const EVENT_TOUCH_END: string;
export declare const EVENT_POINTER_DOWN: string;
export declare const EVENT_POINTER_MOVE: string;
export declare const EVENT_POINTER_UP: string;
export declare const EVENT_WHEEL = "wheel";
export declare const EVENT_CROP_CHANGE = "crop-change";
export declare const EVENT_CROP_START = "crop-start";
export declare const EVENT_CROP_END = "crop-end";
export declare const REGEXP_SPACES: RegExp;
export declare const REGEXP_ACTIONS: RegExp;

View File

@ -1,9 +0,0 @@
declare const _default: {
bind(): void;
unbind(): void;
onCropStart(event: any): void;
onCropMove(event: any): void;
onCropEnd(event: any): void;
change(event: any): void;
};
export default _default;

View File

@ -1,34 +0,0 @@
import './index.module.scss';
export interface Option {
image?: string | HTMLImageElement;
showMask?: boolean;
cropBoxLimited?: {
width: number;
height: number;
top: number;
left: number;
};
minCropBoxWidth?: number;
minCropBoxHeight?: number;
viewer?: any;
initialCropBoxData?: any;
}
declare class Cropper {
element: HTMLDivElement;
options: Option;
cropped: boolean;
limited: boolean;
image: HTMLImageElement;
eventHandleList: never[];
container: Element;
dragBox: Element;
cropBox: Element;
viewBox: Element;
constructor(element: any, options?: any);
init(): Promise<void>;
initDefaultCropBox(): void;
load(): Promise<HTMLElement>;
build(): void;
destroy(): void;
}
export default Cropper;

View File

@ -1,6 +0,0 @@
declare const _default: {
previewBox: null;
initPreview(): void;
renderPreview(): void;
};
export default _default;

View File

@ -1,20 +0,0 @@
declare const _default: {
cropBoxData: null;
viewBoxImage: null;
render(): void;
initContainer(): void;
initCropBox(): void;
renderCropBox(): void;
clearCropBox(): {
cropBoxData: null;
viewBoxImage: null;
render(): void;
initContainer(): void;
initCropBox(): void;
renderCropBox(): void;
clearCropBox(): any;
limitCropBox(sizeLimited: any, positionLimited: any): void;
};
limitCropBox(sizeLimited: any, positionLimited: any): void;
};
export default _default;

View File

@ -1,7 +0,0 @@
declare const _default: {
initBridge(): void;
onTransformChange(viewer: any): void;
onWheel(event: any): void;
clearBridge(): void;
};
export default _default;

View File

@ -1,4 +0,0 @@
export { default as Cropper } from './cropper';
export { default as Viewer } from './viewer';
export { EVENT_CROP_CHANGE, EVENT_CROP_START, EVENT_CROP_END } from './cropper/constants';
export { EVENT_VIEWER_TRANSFORM_CHANGE, EVENT_VIEWER_READY, EVENT_VIEWER_ERROR, EVENT_SHAPE_SELECT, EVENT_EYE_DONE, } from './viewer/constants';

View File

@ -1,89 +0,0 @@
export declare const IS_BROWSER: boolean;
export declare const WINDOW: {};
export declare const IS_TOUCH_DEVICE: boolean;
export declare const HAS_POINTER_EVENT: boolean;
/**
* Transform the given string from camelCase to kebab-case
* @param {string} value - The value to transform.
* @returns {string} The transformed value.
*/
export declare function toParamCase(value: any): any;
/**
* Get data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to get.
* @returns {string} The data value.
*/
export declare function getData(element: any, name: any): any;
export declare function toggleClass(node: HTMLElement, className: string): void;
/**
* Get a pointer from an event object.
* @param {Object} event - The target event object.
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
* @returns {Object} The result pointer contains start and/or end point coordinates.
*/
export declare function getPointer({ pageX, pageY }: {
pageX: any;
pageY: any;
}, endOnly?: any): {
endX: any;
endY: any;
} | {
endX: any;
endY: any;
startX: any;
startY: any;
};
/**
* Get the offset base on the document.
* @param {Element} element - The target element.
* @returns {Object} The offset data.
*/
export declare function getOffset(element: any): {
left: any;
top: any;
};
/**
* Get transforms base on the given object.
* @param {Object} obj - The target object.
* @returns {string} A string contains transform values.
*/
export declare function getTransforms({ rotate, scaleX, scaleY, translateX, translateY, }: {
rotate?: number;
scaleX?: number;
scaleY?: number;
translateX?: number;
translateY?: number;
}): {
WebkitTransform: string;
msTransform: string;
transform: string;
};
/**
* copy from https://github.com/steelsojka/lodash-decorators/blob/master/src/mixin.ts
* Mixins an object into the classes prototype.
* @export
* @param {...Object[]} srcs
* @returns {ClassDecorator}
* @example
*
* const myMixin = {
* blorg: () => 'blorg!'
* }
*
* @Mixin(myMixin)
* class MyClass {}
*
* const myClass = new MyClass();
*
* myClass.blorg(); // => 'blorg!'
*/
export declare function Mixin(...srcs: Object[]): ClassDecorator;
/**
* Dispatch event on the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Object} data - The additional event data.
* @returns {boolean} Indicate if the event is default prevented or not.
*/
export declare function dispatchEvent(element: any, type: any, data?: any): any;

View File

@ -1,26 +0,0 @@
export declare const NAMESPACE = "zhst-viewer";
export declare const ACTION_DRAG = "drag";
export declare const CLASS_CANVAS: string;
export declare const CLASS_MOVE: string;
export declare const EVENT_CLICK = "click";
export declare const EVENT_TOUCH_START: string;
export declare const EVENT_TOUCH_MOVE: string;
export declare const EVENT_TOUCH_END: string;
export declare const EVENT_POINTER_DOWN: string;
export declare const EVENT_POINTER_MOVE: string;
export declare const EVENT_POINTER_UP: string;
export declare const EVENT_WHEEL = "wheel";
export declare const EVENT_LEAVEL = "mouseleave";
export declare const EVENT_ENTER = "mouseenter";
export declare const EVENT_VIEWER_TRANSFORM_CHANGE = "viewer-transform-change";
export declare const EVENT_VIEWER_READY = "viewer-ready";
export declare const EVENT_VIEWER_ERROR = "viewer-error";
export declare const EVENT_SHAPE_SELECT = "shape-select";
export declare const EVENT_EYE_DONE = "eye-done";
export declare const REGEXP_SPACES: RegExp;
export declare const AXIS_TYPE_ORIGIN = 1;
export declare const AXIS_TYPE_CANVAS = 2;
export declare const AXIS_TYPE_IMAGE = 3;
export declare const SHAPE_TYPE_CUSTOM = 1;
export declare const SHAPE_TYPE_RECT = 2;
export declare const SHAPE_TYPE_CIRCLE = 3;

View File

@ -1,15 +0,0 @@
declare const _default: {
disabled: boolean;
eventHandleList: never[];
wheeling: boolean;
pointer: null;
action: null;
bind(): void;
unbind(): void;
onWheel(event: any, cropBox?: any): void;
onDragStart(event: any): void;
onDragMove(event: any): void;
onDragEnd(event: any): void;
onClick(event: any): void;
};
export default _default;

View File

@ -1,43 +0,0 @@
export declare const setNumberAccuracy: (originNumber: number, accuracy?: number, isCeil?: boolean) => number;
declare const _default: {
windowToCanvasAxis(event: any): any;
offsetAxisToCanvasAxis({ x, y }: {
x: any;
y: any;
}): any;
originAxisToCanvasAxis({ x, y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
canvasAxisToOriginAxis({ x, y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
imgRectAxisToCanvasAxisRect({ x, y, w, h, ...others }: {
[x: string]: any;
x?: number | undefined;
y?: number | undefined;
w?: number | undefined;
h?: number | undefined;
}): any;
originAxisToImgAxis({ x, y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
imgAxisToOriginAxis({ x: _x, y: _y, ...others }: {
[x: string]: any;
x: any;
y: any;
}): any;
getDataUrlbyOriginAxis({ x, y, w, h, ...others }: {
[x: string]: any;
x?: number | undefined;
y?: number | undefined;
w?: number | undefined;
h?: number | undefined;
}): string;
};
export default _default;

View File

@ -1,21 +0,0 @@
import './index.scss';
export interface Option {
image?: string | HTMLImageElement;
wheelZoomRatio?: number;
scaleAble?: boolean;
dragAble?: boolean;
fitScaleAsMinScale?: boolean;
}
declare class Viewer {
element: HTMLDivElement;
image: HTMLImageElement;
canvas: Element;
options: Option;
ready: boolean;
constructor(element: any, options: any);
init(): Promise<void>;
build(): void;
refleshImage(options: any): void;
destroy(): void;
}
export default Viewer;

View File

@ -1,35 +0,0 @@
declare const _default: {
image: null;
canvas: null;
containerData: {
width: number;
height: number;
};
animationFrame: null;
backgroundColor: string;
targetTransform: {
translateX: number;
translateY: number;
scale: number;
rotate: number;
};
render(): Promise<void>;
initImg(): Promise<HTMLElement>;
initCanvas(): void;
startRaf(): void;
renderCanvas(_ctx: any): void;
scaleTo(offsetScale: any): void;
rotateTo(T: number | ((preDeg: number) => number)): void;
reset(): void;
getImgSize(): {
w: any;
h: any;
} | undefined;
calcFitScreen(): {
translateX: number;
translateY: number;
scale: number;
} | undefined;
calcTransform(newTransform: any, cropBox: any): void;
};
export default _default;

View File

@ -1,40 +0,0 @@
export interface Shape {
id: number | string;
selectAble: boolean;
color: string;
}
export interface Rect extends Shape {
x: number;
y: number;
w: number;
h: number;
}
export interface Point extends Shape {
x: number;
y: number;
}
declare const _default: {
shapeList: never[];
hoverShapId: null;
selectShapId: null;
isEyeOpen: boolean;
movable: boolean;
zoomable: boolean;
disableAdd: boolean;
color: string;
changeEyeModel(isOpen: any): void;
addShape(shap: Shape | Array<Shape>, type?: number): void;
setSelectShapId(id: number): void;
getSelectShape(contain?: boolean): any[];
replaceShape(shape: Shape | Shape[] | ((shape: Shape) => Shape | Array<Shape>), type?: number): void;
clearShape(): void;
calcSelectShape(canvasPoint: any): null;
clearSelectShape(): void;
changeMoveAble(movable?: boolean): void;
changeZoonAble(zoomable?: boolean): void;
disabledAddShap(value?: boolean): void;
renderShape(ctx: any): void;
renderRect(ctx: any, shape: any, type: any): void;
renderPoint(ctx: any, shape: any): void;
};
export default _default;

View File

@ -1,6 +0,0 @@
import { FC } from 'react';
import type { ButtonProps } from 'antd/lib/button';
interface IButtonDemo extends ButtonProps {
}
declare const ButtonDemo: FC<IButtonDemo>;
export default ButtonDemo;

View File

@ -1,18 +0,0 @@
import React, { Dispatch, ReactElement, SetStateAction } from 'react';
import { Rect, IScreenshotButtonProp, AlignType } from '@zhst/types';
import './index.less';
export interface VideoViewProps {
url: string;
maxDuration?: number;
screenshotButtonAlign?: AlignType;
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
defautlNormalizationRect?: Rect;
onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void;
}
export interface VideoViewRef {
cropAble: boolean;
setShowCrop: Dispatch<SetStateAction<boolean>>;
downloadVideoframe: () => void;
}
declare const VideoPlayer: React.ForwardRefExoticComponent<VideoViewProps & React.RefAttributes<VideoViewRef>>;
export default VideoPlayer;

View File

@ -1,46 +0,0 @@
import React, { Component, CSSProperties } from 'react';
import flvjs from 'flv.js';
export declare const FLV_EVENT: Readonly<flvjs.Events>;
export interface VideoPlayerProps {
className: string;
style?: CSSProperties;
type: string;
isLive?: boolean;
cors?: boolean;
withCredentials?: boolean;
playId?: number;
hasAudio?: boolean;
hasVideo?: boolean;
duration?: number;
filesize?: number;
url?: string;
autoPlay?: boolean;
onCreat?: any;
/**
* @see https://github.com/Bilibili/flv.js/blob/master/docs/api.md#config
*/
config: object;
}
export default class VideoPlayer extends Component<VideoPlayerProps, any> {
state: {
curPlayUrl: string;
shouldReinit: boolean;
};
flvPlayer: any;
videoElement: null;
static getDerivedStateFromProps: (nextProps: {
url?: any;
playId?: any;
}, prevState: {
curPlayUrl?: any;
playId?: any;
}) => {
playId: any;
curPlayUrl: any;
shouldReinit: boolean;
} | null;
initFlv: ($video: null) => void;
componentWillUnmount(): void;
componentDidUpdate(): void;
render(): React.JSX.Element;
}

View File

@ -1,8 +0,0 @@
import { FC } from 'react';
import './index.less';
export interface ILoading {
status: 'LOADING' | 'COMPLETED' | 'END' | 'ERROR' | null;
reload: () => void;
}
declare const Loading: FC<ILoading>;
export default Loading;

View File

@ -1,10 +0,0 @@
import React from 'react';
import type { SliderSingleProps } from 'antd';
import './index.less';
export interface RangeWrapperProps extends SliderSingleProps {
showSlider: boolean;
className?: string;
min: number;
}
export declare const Range: React.FC<RangeWrapperProps>;
export default Range;

View File

@ -1,3 +0,0 @@
import VideoPlayer from './VideoPlayer';
export type { VideoViewProps, VideoViewRef } from './VideoPlayer';
export default VideoPlayer;

View File

@ -1 +0,0 @@
export declare function getShowStatus(isLoadingVideo: boolean, isEnd: boolean, isError: boolean): string | null;

View File

@ -1,5 +0,0 @@
export declare const doubleCheck: (title?: string, option?: any) => {
destroy: () => void;
update: (configUpdate: import("antd").ModalFuncProps | ((prevConfig: import("antd").ModalFuncProps) => import("antd").ModalFuncProps)) => void;
};
export default doubleCheck;

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
import React from 'react';
import './iconfont.css';
interface IconFontProps {
styles?: React.CSSProperties;
icon?: string;
size?: number;
color?: string;
title?: string;
className?: string;
onIconClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
children?: React.ReactNode;
active?: boolean;
disable?: boolean;
}
declare const IconFont: React.FC<IconFontProps>;
export default IconFont;

View File

@ -1,5 +0,0 @@
export { default as doubleClick } from './doubleClick';
export { default as Icon } from './iconfont';
export { default as CompareImage } from './CompareImage';
export { default as BigImagePreview } from './BigImagePreview';
export { default as VideoPlayer } from './VideoPlayer';

View File

@ -30,8 +30,25 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
var src_exports = {};
__export(src_exports, {
BigImagePreview: () => import_BigImagePreview.default,
Button: () => import_button.default,
Calender: () => import_calendar.default,
CheckBox: () => import_checkbox.default,
CompareImage: () => import_CompareImage.default,
ConfigProvider: () => import_config_provider.default,
DatePicker: () => import_date_picker.default,
Empty: () => import_empty.default,
Form: () => import_form.default,
Grid: () => import_grid.default,
Icon: () => import_iconfont.default,
Input: () => import_input.default,
Locale: () => import_locale.default,
Radio: () => import_radio.default,
Select: () => import_select.default,
Space: () => import_space.default,
Switch: () => import_switch.default,
Tabs: () => import_tabs.default,
Theme: () => import_theme.default,
TimePicker: () => import_time_picker.default,
VideoPlayer: () => import_VideoPlayer.default,
doubleClick: () => import_doubleClick.default
});
@ -41,11 +58,45 @@ var import_iconfont = __toESM(require("./iconfont"));
var import_CompareImage = __toESM(require("./CompareImage"));
var import_BigImagePreview = __toESM(require("./BigImagePreview"));
var import_VideoPlayer = __toESM(require("./VideoPlayer"));
var import_tabs = __toESM(require("./tabs"));
var import_button = __toESM(require("./button"));
var import_space = __toESM(require("./space"));
var import_switch = __toESM(require("./switch"));
var import_grid = __toESM(require("./grid"));
var import_time_picker = __toESM(require("./time-picker"));
var import_date_picker = __toESM(require("./date-picker"));
var import_calendar = __toESM(require("./calendar"));
var import_empty = __toESM(require("./empty"));
var import_form = __toESM(require("./form"));
var import_select = __toESM(require("./select"));
var import_radio = __toESM(require("./radio"));
var import_checkbox = __toESM(require("./checkbox"));
var import_input = __toESM(require("./input"));
var import_config_provider = __toESM(require("./config-provider"));
var import_theme = __toESM(require("./theme"));
var import_locale = __toESM(require("./locale"));
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
BigImagePreview,
Button,
Calender,
CheckBox,
CompareImage,
ConfigProvider,
DatePicker,
Empty,
Form,
Grid,
Icon,
Input,
Locale,
Radio,
Select,
Space,
Switch,
Tabs,
Theme,
TimePicker,
VideoPlayer,
doubleClick
});

View File

@ -1,12 +0,0 @@
export declare const CROP_TYPE: {
CUSTOM: string;
AUTO: string;
};
export declare const defaultAlignOption: {
points: string[];
offset: number[];
overflow: {
adjustX: boolean;
adjustY: boolean;
};
};

View File

View File

@ -1,6 +1,6 @@
{
"name": "@zhst/meta",
"version": "0.3.1",
"version": "0.4.0",
"description": "原子组件",
"keywords": [
"meta",
@ -36,18 +36,37 @@
"@zhst/types": "workspace:^"
},
"dependencies": {
"@ant-design/colors": "^7.0.2",
"@ant-design/cssinjs": "^1.18.2",
"@ant-design/icons": "^5.2.6",
"@ctrl/tinycolor": "^4.0.2",
"@rc-component/trigger": "^1.18.2",
"@turf/boolean-point-in-polygon": "^6.5.0",
"@turf/turf": "^6.5.0",
"@types/downloadjs": "^1.4.6",
"@zhst/func": "workspace:^",
"@zhst/hooks": "workspace:^",
"antd": "^5.12.5",
"antd-style": "^3.6.1",
"classnames": "^2.5.1",
"dayjs": "^1.11.10",
"downloadjs": "^1.4.7",
"flv.js": "^1.6.2",
"rc-align": "^4.0.15",
"rc-checkbox": "^3.1.0",
"rc-field-form": "^1.41.0",
"rc-input": "^1.4.3",
"rc-motion": "^2.9.0",
"rc-pagination": "^4.0.4",
"rc-picker": "4.0.0-alpha.36",
"rc-select": "^14.11.0",
"rc-switch": "^4.1.0",
"rc-tabs": "^14.0.0",
"rc-textarea": "^1.6.3",
"rc-tooltip": "^6.1.3",
"rc-util": "^5.38.1",
"react": "^18.0.0",
"react-dom": "^18.0.0"
"react-dom": "^18.0.0",
"scroll-into-view-if-needed": "^3.1.0"
}
}

View File

@ -1,10 +1,8 @@
---
nav:
title: 元组件
order: 1
group:
title: 通用
order: 3
group: 通用
category: Components
subtitle: 大图预览组件
title: BigImagePreview 大图预览组件
---
# BigImagePreview 大图预览组件
@ -184,12 +182,14 @@ export default () => {
}
```
| 参数名 | 参数类型 | 参数说明 |
| ------ | -------- | ---- |
| imageKey | string必填 | 当前大图链接 |
| odRect | { x: number; y: number; w: number; h: number } | 圈选矩形 |
|height|string选填|高度|
|width|string选填|宽度|
|score|string选填|相似度|
|attachImg|{ url: string; label: string; }[](选填)|缩略图|
|objects | IOdRectOrigin[] | 编辑状态参数 |
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| imageKey | 当前大图链接 | string必填 | - | |
| odRect | 圈选矩形参数 | { x: number; y: number; w: number; h: number } | - | |
| height | 高度 | number选填 | - | |
| width | 宽度 | number选填 | - | |
| score | 相似度 | number选填 | - | |
| attachImg | 缩略图 | { url: string; label: string; }[](选填) | - | |
| objects | 编辑状态参数 | IOdRectOrigin[](选填) | - | |

View File

@ -1,18 +1,15 @@
---
nav:
title: 元组件
order: 1
group:
title: 通用
order: 3
group: 通用
category: Components
subtitle: 图片预览
title: CompareImage 图片预览
---
# CompareImage 图片预览
```jsx
import React, { useRef } from 'react';
import { CompareImage } from '@zhst/meta'
import { Button, Space } from 'antd'
import { CompareImage, Space, Button } from '@zhst/meta'
const props = {
label: "目标图",
@ -42,9 +39,13 @@ export default () => {
}
```
| 参数名 | 参数类型 | 参数说明 |
| ------ | -------- | ---- |
|label|string|左上角标题|
|openRoll|boolean|是否支持鼠标滚动放大缩小|
|urls|string[]|链接数组|
|score|string|相似度|
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| label | 左上角标题 | string必填 | - | |
| openRoll | 是否支持鼠标滚动放大缩小 | boolean | - | |
| urls | 链接数组 | string[] | - | |
| width | 宽度 | string选填 | - | |
| height | 高度 | string选填 | - | |
| score | 相似度 | string选填 | - | |

View File

@ -1,10 +1,8 @@
---
nav:
title: 元组件
order: 1
group:
title: 通用
order: 3
group: 通用
category: Components
subtitle: 视频播放
title: VideoPlayer 视频播放
---
# VideoPlayer 视频播放
@ -15,8 +13,7 @@ group:
```jsx
import React, { useRef, useState } from 'react';
import { Space, Button } from 'antd'
import { VideoPlayer } from '@zhst/meta'
import { VideoPlayer, Space, Button } from '@zhst/meta'
export default () => {
const videoRef = useRef(null)
@ -33,7 +30,9 @@ export default () => {
}
```
| 参数名 | 参数类型 | 参数说明 |
| ------ | -------- | ---- |
| url | string必填 | 当前视频链接 |
| maxDuration | number选填 | 默认20s, 视频截取长度(注意视频原始长度) |
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| url | 当前视频链接 | string必填 | - | |
| maxDuration | 视频截取长度(注意视频原始长度) | number选填 | - | |

View File

@ -0,0 +1,135 @@
import useState from 'rc-util/lib/hooks/useState';
import * as React from 'react';
import Button from '../button';
import type { ButtonProps, LegacyButtonType } from '../button/button';
import { convertLegacyProps } from '../button/buttonHelpers';
export interface ActionButtonProps {
type?: LegacyButtonType;
actionFn?: (...args: any[]) => any | PromiseLike<any>;
close?: Function;
autoFocus?: boolean;
prefixCls: string;
buttonProps?: ButtonProps;
emitEvent?: boolean;
quitOnNullishReturnValue?: boolean;
children?: React.ReactNode;
/**
* Do not throw if is await mode
*/
isSilent?: () => boolean;
}
function isThenable<T extends any>(thing?: PromiseLike<T>): boolean {
return !!(thing && thing.then);
}
const ActionButton: React.FC<ActionButtonProps> = (props) => {
const {
type,
children,
prefixCls,
buttonProps,
close,
autoFocus,
emitEvent,
isSilent,
quitOnNullishReturnValue,
actionFn,
} = props;
const clickedRef = React.useRef<boolean>(false);
const buttonRef = React.useRef<HTMLButtonElement | HTMLAnchorElement>(null);
const [loading, setLoading] = useState<ButtonProps['loading']>(false);
const onInternalClose = (...args: any[]) => {
close?.(...args);
};
React.useEffect(() => {
let timeoutId: ReturnType<typeof setTimeout> | null = null;
if (autoFocus) {
timeoutId = setTimeout(() => {
buttonRef.current?.focus();
});
}
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, []);
const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
if (!isThenable(returnValueOfOnOk)) {
return;
}
setLoading(true);
returnValueOfOnOk!.then(
(...args: any[]) => {
setLoading(false, true);
onInternalClose(...args);
clickedRef.current = false;
},
(e: Error) => {
// See: https://github.com/ant-design/ant-design/issues/6183
setLoading(false, true);
clickedRef.current = false;
// Do not throw if is `await` mode
if (isSilent?.()) {
return;
}
return Promise.reject(e);
},
);
};
const onClick = (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
if (clickedRef.current) {
return;
}
clickedRef.current = true;
if (!actionFn) {
onInternalClose();
return;
}
let returnValueOfOnOk: PromiseLike<any>;
if (emitEvent) {
returnValueOfOnOk = actionFn(e);
if (quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) {
clickedRef.current = false;
onInternalClose(e);
return;
}
} else if (actionFn.length) {
returnValueOfOnOk = actionFn(close);
// https://github.com/ant-design/ant-design/issues/23358
clickedRef.current = false;
} else {
returnValueOfOnOk = actionFn();
if (!returnValueOfOnOk) {
onInternalClose();
return;
}
}
handlePromiseOnOk(returnValueOfOnOk);
};
return (
<Button
{...convertLegacyProps(type)}
onClick={onClick}
loading={loading}
prefixCls={prefixCls}
{...buttonProps}
ref={buttonRef}
>
{children}
</Button>
);
};
export default ActionButton;

View File

@ -0,0 +1,101 @@
import * as React from 'react';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import ConfigProvider, { ConfigContext } from '../config-provider';
import type { AnyObject } from './type';
export function withPureRenderTheme<T extends AnyObject = AnyObject>(Component: React.FC<T>) {
return (props: T) => (
<ConfigProvider theme={{ token: { motion: false, zIndexPopupBase: 0 } }}>
<Component {...props} />
</ConfigProvider>
);
}
export interface BaseProps {
prefixCls?: string;
style?: React.CSSProperties;
}
/* istanbul ignore next */
const genPurePanel = <ComponentProps extends BaseProps = BaseProps>(
Component: any,
defaultPrefixCls?: string,
getDropdownCls?: null | ((prefixCls: string) => string),
postProps?: (props: ComponentProps) => ComponentProps,
) => {
type WrapProps = ComponentProps & AnyObject;
const PurePanel: React.FC<WrapProps> = (props) => {
const { prefixCls: customizePrefixCls, style } = props;
const holderRef = React.useRef<HTMLDivElement>(null);
const [popupHeight, setPopupHeight] = React.useState(0);
const [popupWidth, setPopupWidth] = React.useState(0);
const [open, setOpen] = useMergedState(false, {
value: props.open,
});
const { getPrefixCls } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls(defaultPrefixCls || 'select', customizePrefixCls);
React.useEffect(() => {
// We do not care about ssr
setOpen(true);
if (typeof ResizeObserver !== 'undefined') {
const resizeObserver = new ResizeObserver((entries) => {
const element: HTMLDivElement = entries[0].target as any;
setPopupHeight(element.offsetHeight + 8);
setPopupWidth(element.offsetWidth);
});
const interval = setInterval(() => {
const dropdownCls = getDropdownCls
? `.${getDropdownCls(prefixCls)}`
: `.${prefixCls}-dropdown`;
const popup = holderRef.current?.querySelector(dropdownCls);
if (popup) {
clearInterval(interval);
resizeObserver.observe(popup);
}
}, 10);
return () => {
clearInterval(interval);
resizeObserver.disconnect();
};
}
}, []);
let mergedProps: WrapProps = {
...props,
style: {
...style,
margin: 0,
},
open,
visible: open,
getPopupContainer: () => holderRef.current!,
};
if (postProps) {
mergedProps = postProps(mergedProps);
}
const mergedStyle: React.CSSProperties = {
paddingBottom: popupHeight,
position: 'relative',
minWidth: popupWidth,
};
return (
<div ref={holderRef} style={mergedStyle}>
<Component {...mergedProps} />
</div>
);
};
return withPureRenderTheme<AnyObject>(PurePanel);
};
export default genPurePanel;

View File

@ -0,0 +1,17 @@
import capitalize from '../capitalize';
describe('capitalize', () => {
it('should capitalize the first character of a string', () => {
expect(capitalize('antd')).toBe('Antd');
expect(capitalize('Antd')).toBe('Antd');
expect(capitalize(' antd')).toBe(' antd');
expect(capitalize('')).toBe('');
});
it('should return the original value when is not a string', () => {
expect(capitalize(1 as any)).toBe(1);
expect(capitalize(true as any)).toBe(true);
expect(capitalize(undefined as any)).toBe(undefined);
expect(capitalize(null as any)).toBe(null);
});
});

View File

@ -0,0 +1,12 @@
import { easeInOutCubic } from '../easings';
describe('Test easings', () => {
it('easeInOutCubic return value', () => {
const nums: number[] = [];
for (let index = 0; index < 5; index++) {
nums.push(easeInOutCubic(index, 1, 5, 4));
}
expect(nums).toEqual([1, 1.25, 3, 4.75, 5]);
});
});

View File

@ -0,0 +1,57 @@
import getScroll from '../getScroll';
describe('getScroll', () => {
it('getScroll target null', async () => {
expect(getScroll(null, true)).toBe(0);
expect(getScroll(null, false)).toBe(0);
});
it('getScroll window', async () => {
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
window.pageXOffset = x;
window.pageYOffset = y;
});
window.scrollTo(200, 400);
expect(getScroll(window, true)).toBe(400);
expect(getScroll(window, false)).toBe(200);
scrollToSpy.mockRestore();
});
it('getScroll document', async () => {
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
document.documentElement.scrollLeft = x;
document.documentElement.scrollTop = y;
});
window.scrollTo(200, 400);
expect(getScroll(document, true)).toBe(400);
expect(getScroll(document, false)).toBe(200);
scrollToSpy.mockRestore();
});
it('getScroll div', async () => {
const div = document.createElement('div');
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
div.scrollLeft = x;
div.scrollTop = y;
});
window.scrollTo(200, 400);
expect(getScroll(div, true)).toBe(400);
expect(getScroll(div, false)).toBe(200);
scrollToSpy.mockRestore();
});
it('getScroll documentElement', async () => {
const div: any = {};
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
div.scrollLeft = null;
div.scrollTop = null;
div.documentElement = {};
div.documentElement.scrollLeft = x;
div.documentElement.scrollTop = y;
});
window.scrollTo(200, 400);
expect(getScroll(div, true)).toBe(400);
expect(getScroll(div, false)).toBe(200);
scrollToSpy.mockRestore();
});
});

View File

@ -0,0 +1,9 @@
/** @jest-environment node */
import getScroll from '../getScroll';
describe('getScroll node', () => {
it('getScroll return 0 in node environment', async () => {
expect(getScroll(null, true)).toBe(0);
expect(getScroll(null, false)).toBe(0);
});
});

View File

@ -0,0 +1,181 @@
import { CloseOutlined } from '@ant-design/icons';
import { render } from '@testing-library/react';
import React, { useEffect } from 'react';
import type { UseClosableParams } from '../hooks/useClosable';
import useClosable from '../hooks/useClosable';
type ParamsOfUseClosable = [
UseClosableParams['closable'],
UseClosableParams['closeIcon'],
UseClosableParams['defaultClosable'],
];
describe('hooks test', () => {
const useClosableParams: { params: ParamsOfUseClosable; res: [boolean, string] }[] = [
// test case like: <Component />
{
params: [undefined, undefined, undefined],
res: [false, ''],
},
{
params: [undefined, undefined, true],
res: [true, 'anticon-close'],
},
{
params: [undefined, undefined, false],
res: [false, ''],
},
// test case like: <Component closable={false | true} />
{
params: [false, undefined, undefined],
res: [false, ''],
},
{
params: [true, undefined, true],
res: [true, 'anticon-close'],
},
{
params: [true, undefined, false],
res: [true, 'anticon-close'],
},
// test case like: <Component closable={false | true} closeIcon={null | false | element} />
{
params: [false, null, undefined],
res: [false, ''],
},
{
params: [false, false, undefined],
res: [false, ''],
},
{
params: [true, null, true],
res: [true, 'anticon-close'],
},
{
params: [true, false, true],
res: [true, 'anticon-close'],
},
{
params: [true, null, false],
res: [true, 'anticon-close'],
},
{
params: [true, false, false],
res: [true, 'anticon-close'],
},
{
params: [
true,
<div className="custom-close" key="close">
close
</div>,
false,
],
res: [true, 'custom-close'],
},
{
params: [false, <div key="close">close</div>, false],
res: [false, ''],
},
// test case like: <Component closeIcon={null | false | element} />
{
params: [undefined, null, undefined],
res: [false, ''],
},
{
params: [undefined, false, undefined],
res: [false, ''],
},
{
params: [
undefined,
<div className="custom-close" key="close">
close
</div>,
undefined,
],
res: [true, 'custom-close'],
},
{
params: [
undefined,
<div className="custom-close" key="close">
close
</div>,
true,
],
res: [true, 'custom-close'],
},
{
params: [
undefined,
<div className="custom-close" key="close">
close
</div>,
false,
],
res: [true, 'custom-close'],
},
];
useClosableParams.forEach(({ params, res }) => {
it(`useClosable with closable=${params[0]},closeIcon=${
React.isValidElement(params[1]) ? 'element' : params[1]
},defaultClosable=${params[2]}. the result should be ${res}`, () => {
const App = () => {
const [closable, closeIcon] = useClosable(
params[0],
params[1],
undefined,
undefined,
params[2],
);
useEffect(() => {
expect(closable).toBe(res[0]);
}, [closable]);
return <div>hooks test {closeIcon}</div>;
};
const { container } = render(<App />);
if (res[1] === '') {
expect(container.querySelector('.anticon-close')).toBeFalsy();
} else {
expect(container.querySelector(`.${res[1]}`)).toBeTruthy();
}
});
});
it('useClosable with defaultCloseIcon', () => {
const App = () => {
const [closable, closeIcon] = useClosable(
true,
undefined,
undefined,
<CloseOutlined className="custom-close-icon" />,
);
useEffect(() => {
expect(closable).toBe(true);
}, [closable]);
return <div>hooks test {closeIcon}</div>;
};
const { container } = render(<App />);
expect(container.querySelector('.custom-close-icon')).toBeTruthy();
});
it('useClosable with customCloseIconRender', () => {
const App = () => {
const customCloseIconRender = (icon: React.ReactNode) => (
<span className="custom-close-wrapper">{icon}</span>
);
const [closable, closeIcon] = useClosable(true, undefined, customCloseIconRender);
useEffect(() => {
expect(closable).toBe(true);
}, [closable]);
return <div>hooks test {closeIcon}</div>;
};
const { container } = render(<App />);
expect(container.querySelector('.custom-close-wrapper')).toBeTruthy();
});
});

View File

@ -0,0 +1,23 @@
import React from 'react';
import { isValidElement, cloneElement, isFragment, replaceElement } from '../reactNode';
describe('reactNode test', () => {
it('isValidElement', () => {
expect(isValidElement(null)).toBe(false);
expect(isValidElement(<p>test</p>)).toBe(true);
});
it('isFragment', () => {
expect(isFragment(<p>test</p>)).toBe(false);
expect(isFragment(<>test</>)).toBe(true);
});
it('replaceElement', () => {
const node = <p>test</p>;
expect(replaceElement(null, node)).toBe(node);
expect(replaceElement(node, node)).toStrictEqual(node);
});
it('cloneElement', () => {
const node = <p>test</p>;
expect(cloneElement(null)).toBe(null);
expect(cloneElement(node)).toStrictEqual(node);
});
});

View File

@ -0,0 +1,26 @@
import React from 'react';
import { render } from '../../../tests/utils';
import useResponsiveObserver from '../responsiveObserver';
describe('Test ResponsiveObserve', () => {
it('test ResponsiveObserve subscribe and unsubscribe', () => {
let responsiveObserveRef: any;
const Demo = () => {
const responsiveObserver = useResponsiveObserver();
responsiveObserveRef = responsiveObserver;
return null;
};
render(<Demo />);
const subscribeFunc = jest.fn();
const token = responsiveObserveRef.subscribe(subscribeFunc);
expect(
responsiveObserveRef.matchHandlers[responsiveObserveRef.responsiveMap.xs].mql.matches,
).toBeTruthy();
expect(subscribeFunc).toHaveBeenCalledTimes(1);
responsiveObserveRef.unsubscribe(token);
expect(
responsiveObserveRef.matchHandlers[responsiveObserveRef.responsiveMap.xs].mql.removeListener,
).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,72 @@
import { waitFakeTimer } from '../../../tests/utils';
import scrollTo from '../scrollTo';
describe('Test ScrollTo function', () => {
const dateNowMock = jest.spyOn(Date, 'now');
beforeAll(() => {
jest.useFakeTimers();
});
beforeEach(() => {
dateNowMock.mockReturnValueOnce(0).mockReturnValueOnce(1000);
});
afterAll(() => {
jest.useRealTimers();
});
afterEach(() => {
jest.clearAllTimers();
dateNowMock.mockClear();
});
it('test scrollTo', async () => {
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((_, y) => {
window.scrollY = y;
window.pageYOffset = y;
});
scrollTo(1000);
await waitFakeTimer();
expect(window.pageYOffset).toBe(1000);
scrollToSpy.mockRestore();
});
it('test callback - option', async () => {
const cbMock = jest.fn();
scrollTo(1000, {
callback: cbMock,
});
await waitFakeTimer();
expect(cbMock).toHaveBeenCalledTimes(1);
});
it('test getContainer - option', async () => {
const div = document.createElement('div');
scrollTo(1000, {
getContainer: () => div,
});
await waitFakeTimer();
expect(div.scrollTop).toBe(1000);
});
it('test getContainer document - option', async () => {
scrollTo(1000, {
getContainer: () => document,
});
await waitFakeTimer();
expect(document.documentElement.scrollTop).toBe(1000);
});
it('test duration - option', async () => {
scrollTo(1000, {
duration: 1100,
getContainer: () => document,
});
await waitFakeTimer();
expect(document.documentElement.scrollTop).toBe(1000);
});
});

View File

@ -0,0 +1,10 @@
import React from 'react';
import TransButton from '../transButton';
import { render } from '../../../tests/utils';
describe('transButton component', () => {
it('disabled should update style', () => {
const { container } = render(<TransButton disabled />);
expect(container.querySelector('div')?.style.pointerEvents).toBe('none');
});
});

View File

@ -0,0 +1,17 @@
import React from 'react';
import useSyncState from '../hooks/useSyncState';
import { render, fireEvent } from '../../../tests/utils';
describe('Table', () => {
it('useSyncState', () => {
const Test = () => {
const [getVal, setVal] = useSyncState('light');
return <span onClick={() => setVal('bamboo')}>{getVal()}</span>;
};
const { container } = render(<Test />);
expect(container.querySelector('span')?.innerHTML).toBe('light');
fireEvent.click(container.querySelector('span')!);
expect(container.querySelector('span')?.innerHTML).toBe('bamboo');
});
});

View File

@ -0,0 +1,397 @@
import type { PropsWithChildren } from 'react';
import React, { useEffect } from 'react';
import { render } from '@testing-library/react';
import type { ImageProps, MenuProps } from 'antd';
import {
AutoComplete,
Cascader,
ColorPicker,
DatePicker,
Drawer,
Dropdown,
Image,
Menu,
Modal,
Popconfirm,
Popover,
Select,
Tooltip,
Tour,
TreeSelect,
} from 'antd';
import { waitFakeTimer } from '../../../tests/utils';
import type { ZIndexConsumer, ZIndexContainer } from '../hooks/useZIndex';
import { consumerBaseZIndexOffset, containerBaseZIndexOffset, useZIndex } from '../hooks/useZIndex';
import zIndexContext from '../zindexContext';
const WrapWithProvider: React.FC<PropsWithChildren<{ containerType: ZIndexContainer }>> = ({
children,
containerType,
}) => {
const [, contextZIndex] = useZIndex(containerType);
return <zIndexContext.Provider value={contextZIndex}>{children}</zIndexContext.Provider>;
};
const containerComponent: Record<
ZIndexContainer,
React.FC<PropsWithChildren<{ rootClassName?: string }>>
> = {
Modal: ({ children, ...restProps }) => (
<Modal {...restProps} open>
{children}
</Modal>
),
Drawer: ({ children, ...restProps }) => (
<Drawer {...restProps} open>
{children}
</Drawer>
),
Popover: ({ children, ...restProps }) => (
<Popover {...restProps} open content="test">
{children}
</Popover>
),
Popconfirm: ({ children, ...restProps }) => (
<Popconfirm {...restProps} open title="test">
{children}
</Popconfirm>
),
Tooltip: ({ children, ...restProps }) => (
<Tooltip {...restProps} open title="test">
{children}
</Tooltip>
),
Tour: ({ children, ...restProps }) => (
<Tour
{...restProps}
open
steps={[
{
title: 'cover title',
description: children,
},
]}
/>
),
};
const options = [
{
label: 'Option 1',
value: '1',
},
{
label: 'Option 2',
value: '2',
},
];
const items: MenuProps['items'] = [
{
label: 'Test',
key: 'SubMenu',
children: [
{
type: 'group',
label: 'Item 1',
children: [
{
label: 'Option 1',
key: 'setting:1',
},
{
label: 'Option 2',
key: 'setting:2',
},
],
},
{
type: 'group',
label: 'Item 2',
children: [
{
label: 'Option 3',
key: 'setting:3',
},
{
label: 'Option 4',
key: 'setting:4',
},
],
},
],
},
];
const consumerComponent: Record<ZIndexConsumer, React.FC<{ rootClassName: string }>> = {
SelectLike: ({ rootClassName, ...props }) => (
<>
<Select
{...props}
rootClassName={`${rootClassName} comp-item comp-Select`}
options={options}
open
/>
<Cascader
{...props}
rootClassName={`${rootClassName} comp-item comp-Cascader`}
options={options}
open
/>
<TreeSelect
{...props}
rootClassName={`${rootClassName} comp-item comp-TreeSelect`}
treeData={options}
open
/>
<AutoComplete
{...props}
rootClassName={`${rootClassName} comp-item comp-AutoComplete`}
options={options}
open
/>
<ColorPicker {...props} open rootClassName={`${rootClassName} comp-item comp-ColorPicker`} />
</>
),
Dropdown: (props) => (
<Dropdown
{...props}
menu={{
items: options.map((item) => ({
key: item.value,
label: item.label,
})),
}}
open
>
<button type="button">test</button>
</Dropdown>
),
DatePicker: ({ rootClassName, ...props }) => (
<>
<DatePicker {...props} rootClassName={`${rootClassName} comp-item comp-DatePicker`} open />
<DatePicker.TimePicker
{...props}
rootClassName={`${rootClassName} comp-item comp-TimePicker`}
open
/>
</>
),
Menu: (props) => <Menu {...props} items={items} defaultOpenKeys={['SubMenu']} />,
ImagePreview: ({ rootClassName }: ImageProps) => (
<>
<Image
src="xxx"
preview={{
visible: true,
rootClassName: `${rootClassName} comp-item comp-ImagePreview`,
}}
/>
<Image.PreviewGroup
preview={{
visible: true,
rootClassName: `${rootClassName} comp-item comp-ImagePreviewGroup`,
}}
>
<Image src="xxx" />
</Image.PreviewGroup>
</>
),
};
function getConsumerSelector(baseSelector: string, consumer: ZIndexConsumer): string {
let selector = baseSelector;
if (consumer === 'SelectLike') {
selector = ['Select', 'Cascader', 'TreeSelect', 'AutoComplete', 'ColorPicker']
.map((item) =>
item === 'ColorPicker'
? `${baseSelector}.ant-popover-placement-bottomLeft`
: `${baseSelector}.comp-${item}.ant-slide-up`,
)
.join(',');
} else if (consumer === 'DatePicker') {
selector = ['DatePicker', 'TimePicker']
.map((item) => `${baseSelector}.comp-${item}.ant-picker-dropdown`)
.join(',');
} else if (['Menu'].includes(consumer)) {
selector = `${baseSelector}.ant-menu-submenu-placement-rightTop`;
} else if (consumer === 'ImagePreview') {
selector = ['ImagePreview', 'ImagePreviewGroup']
.map(
(item) =>
`${baseSelector}.comp-${item} .ant-image-preview-wrap, ${baseSelector}.comp-${item}.ant-image-preview-operations-wrapper`,
)
.join(',');
}
return selector;
}
describe('Test useZIndex hooks', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
const containers = Object.keys(containerComponent);
const consumers = Object.keys(consumerComponent);
containers.forEach((containerKey) => {
consumers.forEach((key) => {
describe(`Test ${key} zIndex in ${containerKey}`, () => {
it('Test hooks', () => {
const fn = jest.fn();
const Child = () => {
const [zIndex] = useZIndex(key as ZIndexConsumer);
useEffect(() => {
fn(zIndex);
}, [zIndex]);
return <div>Child</div>;
};
const App = () => (
<WrapWithProvider containerType={containerKey as ZIndexContainer}>
<WrapWithProvider containerType={containerKey as ZIndexContainer}>
<WrapWithProvider containerType={containerKey as ZIndexContainer}>
<Child />
</WrapWithProvider>
</WrapWithProvider>
</WrapWithProvider>
);
render(<App />);
expect(fn).toHaveBeenLastCalledWith(
1000 +
containerBaseZIndexOffset[containerKey as ZIndexContainer] * 3 +
consumerBaseZIndexOffset[key as ZIndexConsumer],
);
});
it('Test Component', async () => {
const Container = containerComponent[containerKey as ZIndexContainer];
const Consumer = consumerComponent[key as ZIndexConsumer];
const App = () => (
<>
<Consumer rootClassName="consumer1" />
<Container rootClassName="container1">
<Consumer rootClassName="consumer2" />
<Container rootClassName="container2">
<Consumer rootClassName="consumer3" />
</Container>
</Container>
</>
);
const { unmount } = render(<App />);
await waitFakeTimer(1000);
const selector1 = getConsumerSelector('.consumer1', key as ZIndexConsumer);
const selector2 = getConsumerSelector('.consumer2', key as ZIndexConsumer);
const selector3 = getConsumerSelector('.consumer3', key as ZIndexConsumer);
if (['SelectLike', 'DatePicker', 'ImagePreview'].includes(key)) {
let comps = document.querySelectorAll(selector1);
comps.forEach((comp) => {
expect((comp as HTMLDivElement).style.zIndex).toBeFalsy();
});
comps = document.querySelectorAll(selector2);
comps.forEach((comp) => {
const isColorPicker = (comp as HTMLDivElement).className.includes('comp-ColorPicker');
const consumerOffset = isColorPicker
? containerBaseZIndexOffset.Popover
: consumerBaseZIndexOffset[key as ZIndexConsumer];
const operOffset = comp.classList.contains('ant-image-preview-operations-wrapper')
? 1
: 0;
expect((comp as HTMLDivElement).style.zIndex).toBe(
String(
1000 +
containerBaseZIndexOffset[containerKey as ZIndexContainer] +
consumerOffset +
operOffset,
),
);
});
comps = document.querySelectorAll(selector3);
comps.forEach((comp) => {
const isColorPicker = (comp as HTMLDivElement).className.includes('comp-ColorPicker');
const consumerOffset = isColorPicker
? containerBaseZIndexOffset.Popover
: consumerBaseZIndexOffset[key as ZIndexConsumer];
const operOffset = comp.classList.contains('ant-image-preview-operations-wrapper')
? 1
: 0;
expect((comp as HTMLDivElement).style.zIndex).toBe(
String(
1000 +
containerBaseZIndexOffset[containerKey as ZIndexContainer] * 2 +
consumerOffset +
operOffset,
),
);
});
} else {
if (key === 'Tour') {
expect((document.querySelector(selector1) as HTMLDivElement).style.zIndex).toBe(
'1001',
);
} else {
expect(
(document.querySelector(selector1) as HTMLDivElement).style.zIndex,
).toBeFalsy();
}
expect((document.querySelector(selector2) as HTMLDivElement).style.zIndex).toBe(
String(
1000 +
containerBaseZIndexOffset[containerKey as ZIndexContainer] +
consumerBaseZIndexOffset[key as ZIndexConsumer],
),
);
expect((document.querySelector(selector3) as HTMLDivElement).style.zIndex).toBe(
String(
1000 +
containerBaseZIndexOffset[containerKey as ZIndexContainer] * 2 +
consumerBaseZIndexOffset[key as ZIndexConsumer],
),
);
}
unmount();
}, 20000);
});
});
});
it('Modal static func should always use max zIndex', async () => {
jest.useFakeTimers();
const instance = Modal.confirm({
title: 'bamboo',
content: <Select open />,
});
await waitFakeTimer();
expect(document.querySelector('.ant-modal-wrap')).toHaveStyle({
zIndex: '2000',
});
expect(document.querySelector('.ant-select-dropdown')).toHaveStyle({
zIndex: '2050',
});
instance.destroy();
await waitFakeTimer();
// Clean up for static method
document.body.innerHTML = '';
jest.useRealTimers();
});
});

View File

@ -0,0 +1,86 @@
/* eslint-disable class-methods-use-this */
import KeyCode from 'rc-util/lib/KeyCode';
import React from 'react';
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
import { isStyleSupport } from '../styleChecker';
import throttleByAnimationFrame from '../throttleByAnimationFrame';
import TransButton from '../transButton';
describe('Test utils function', () => {
describe('throttle', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
afterEach(() => {
jest.clearAllTimers();
});
it('throttle function should work', async () => {
const callback = jest.fn();
const throttled = throttleByAnimationFrame(callback);
expect(callback).not.toHaveBeenCalled();
throttled();
throttled();
await waitFakeTimer();
expect(callback).toHaveBeenCalled();
expect(callback.mock.calls.length).toBe(1);
});
it('throttle function should be canceled', async () => {
const callback = jest.fn();
const throttled = throttleByAnimationFrame(callback);
throttled();
throttled.cancel();
await waitFakeTimer();
expect(callback).not.toHaveBeenCalled();
});
});
describe('TransButton', () => {
it('can be focus/blur', () => {
const ref = React.createRef<HTMLDivElement>();
render(<TransButton ref={ref}>TransButton</TransButton>);
expect(typeof ref.current?.focus).toBe('function');
expect(typeof ref.current?.blur).toBe('function');
});
it('should trigger onClick when press enter', () => {
const onClick = jest.fn();
const { container } = render(<TransButton onClick={onClick}>TransButton</TransButton>);
// callback should trigger
fireEvent.keyUp(container.querySelector('div')!, { keyCode: KeyCode.ENTER });
expect(onClick).toHaveBeenCalledTimes(1);
// callback should not trigger
fireEvent.keyDown(container.querySelector('div')!, { keyCode: KeyCode.ENTER });
expect(onClick).toHaveBeenCalledTimes(1);
});
});
describe('style', () => {
it('isStyleSupport', () => {
expect(isStyleSupport('color')).toBe(true);
expect(isStyleSupport('not-existed')).toBe(false);
});
it('isStyleSupport return false in service side', () => {
const spy = jest
.spyOn(window.document, 'documentElement', 'get')
.mockImplementation(() => undefined as unknown as HTMLElement);
expect(isStyleSupport('color')).toBe(false);
expect(isStyleSupport('not-existed')).toBe(false);
spy.mockRestore();
});
});
});

Some files were not shown because too many files have changed in this diff Show More