@canlooks/can-ui 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,9 @@ import { ModalProps } from '../modal';
3
3
  import { ReactZoomPanPinchContentRef, ReactZoomPanPinchProps } from 'react-zoom-pan-pinch';
4
4
  export interface ImagePreviewProps extends ModalProps {
5
5
  src?: string | string[];
6
+ defaultIndex?: number;
7
+ index?: number;
8
+ onIndexChange?(index: number): void;
6
9
  defaultOpen?: boolean;
7
10
  onOpenChange?(open: boolean): void;
8
11
  /** 是否渲染旋转按钮{@default true} */
@@ -10,22 +10,22 @@ const icons_1 = require("@ant-design/icons");
10
10
  const button_1 = require("../button");
11
11
  const react_zoom_pan_pinch_1 = require("react-zoom-pan-pinch");
12
12
  const tooltip_1 = require("../tooltip");
13
- exports.ImagePreview = (0, react_1.memo)((0, react_1.forwardRef)(({ src = [], defaultOpen = false, open, onOpenChange, showRotate = true, showZoom = true, showClose = true, renderControl, transformWrapperProps, transformWrapperRef, ...props }, ref) => {
14
- const srcArr = Array.isArray(src) ? src : [src];
13
+ exports.ImagePreview = (0, react_1.memo)((0, react_1.forwardRef)(({ src = [], defaultIndex = 0, index, onIndexChange, defaultOpen = false, open, onOpenChange, showRotate = true, showZoom = true, showClose = true, renderControl, transformWrapperProps, transformWrapperRef, ...props }, ref) => {
14
+ const srcArr = (0, utils_1.toArray)(src);
15
15
  const [innerOpen, setInnerOpen] = (0, utils_1.useControlled)(defaultOpen, open, onOpenChange);
16
- const [activeIndex, setActiveIndex] = (0, react_1.useState)(0);
16
+ const [innerIndex, setInnerIndex] = (0, utils_1.useControlled)(defaultIndex, index, onIndexChange);
17
17
  const innerTransformWrapperRef = (0, react_1.useRef)(null);
18
18
  const imgLoaded = () => {
19
19
  innerTransformWrapperRef.current.centerView();
20
20
  };
21
21
  const prev = (e) => {
22
22
  e.stopPropagation();
23
- setActiveIndex(o => (o - 1 + srcArr.length) % srcArr.length);
23
+ setInnerIndex(o => (o - 1 + srcArr.length) % srcArr.length);
24
24
  innerTransformWrapperRef.current?.resetTransform();
25
25
  };
26
26
  const next = (e) => {
27
27
  e.stopPropagation();
28
- setActiveIndex(o => (o + 1) % srcArr.length);
28
+ setInnerIndex(o => (o + 1) % srcArr.length);
29
29
  innerTransformWrapperRef.current?.resetTransform();
30
30
  };
31
31
  const [rotate, setRotate] = (0, react_1.useState)(0);
@@ -42,7 +42,7 @@ exports.ImagePreview = (0, react_1.memo)((0, react_1.forwardRef)(({ src = [], de
42
42
  (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u65CB\u8F6C-90\u00B0", children: (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: () => setRotate(rotate - 90), children: (0, jsx_runtime_1.jsx)(icons_1.RotateLeftOutlined, {}) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u65CB\u8F6C90\u00B0", children: (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: () => setRotate(rotate + 90), children: (0, jsx_runtime_1.jsx)(icons_1.RotateRightOutlined, {}) }) })] }), showZoom &&
43
43
  (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u7F29\u5C0F", children: (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: () => innerTransformWrapperRef.current.zoomOut(), children: (0, jsx_runtime_1.jsx)(icons_1.ZoomOutOutlined, {}) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u653E\u5927", children: (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: () => innerTransformWrapperRef.current.zoomIn(), children: (0, jsx_runtime_1.jsx)(icons_1.ZoomInOutlined, {}) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u9002\u5E94\u5C4F\u5E55", children: (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: () => innerTransformWrapperRef.current.resetTransform(), children: (0, jsx_runtime_1.jsx)(icons_1.FullscreenOutlined, {}) }) })] }), showClose &&
44
44
  (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: () => setInnerOpen(false), children: (0, jsx_runtime_1.jsx)(icons_1.CloseOutlined, {}) })] }), srcArr.length > 1 &&
45
- (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: imagePreview_style_1.classes.swap, children: [(0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: prev, children: (0, jsx_runtime_1.jsx)(icons_1.LeftOutlined, {}) }), (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: next, children: (0, jsx_runtime_1.jsx)(icons_1.RightOutlined, {}) })] }), (0, jsx_runtime_1.jsxs)("div", { className: imagePreview_style_1.classes.counter, children: [activeIndex + 1, " / ", srcArr.length] })] })] }))
45
+ (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: imagePreview_style_1.classes.swap, children: [(0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: prev, children: (0, jsx_runtime_1.jsx)(icons_1.LeftOutlined, {}) }), (0, jsx_runtime_1.jsx)(button_1.Button, { ...commonControlProps, onClick: next, children: (0, jsx_runtime_1.jsx)(icons_1.RightOutlined, {}) })] }), (0, jsx_runtime_1.jsxs)("div", { className: imagePreview_style_1.classes.counter, children: [innerIndex.current + 1, " / ", srcArr.length] })] })] }))
46
46
  }, children: (0, jsx_runtime_1.jsx)(react_zoom_pan_pinch_1.TransformWrapper, { smooth: false, ...transformWrapperProps, ref: (0, utils_1.cloneRef)(transformWrapperRef, innerTransformWrapperRef), minScale: .2, onPanning: (ref, e) => {
47
47
  transformWrapperProps?.onPanning?.(ref, e);
48
48
  isPanning.current = true;
@@ -51,5 +51,5 @@ exports.ImagePreview = (0, react_1.memo)((0, react_1.forwardRef)(({ src = [], de
51
51
  isPanning.current && setTimeout(() => isPanning.current = false);
52
52
  }, children: (0, jsx_runtime_1.jsx)(react_zoom_pan_pinch_1.TransformComponent, { wrapperClass: imagePreview_style_1.classes.imageWrapper, contentClass: imagePreview_style_1.classes.image, wrapperProps: {
53
53
  onClick: () => !isPanning.current && setInnerOpen(false)
54
- }, children: (0, jsx_runtime_1.jsx)("img", { src: srcArr[activeIndex], style: { rotate: rotate + 'deg' }, onLoad: imgLoaded, alt: "" }) }) }) }));
54
+ }, children: (0, jsx_runtime_1.jsx)("img", { src: srcArr[innerIndex.current], style: { rotate: rotate + 'deg' }, onLoad: imgLoaded, alt: "" }) }) }) }));
55
55
  }));
@@ -371,18 +371,14 @@ exports.Popper = (0, react_1.forwardRef)(({ popperRef, anchorElement, container
371
371
  // click
372
372
  const onClick = (0, react_1.useCallback)((e) => {
373
373
  children?.props.onClick?.(e);
374
- setInnerOpen(openHolding.current = true);
375
- }, [children?.props.onClick]);
376
- const allowClickAway = (() => {
377
- let allow = false;
378
- for (const trigger of triggersSet) {
379
- if (trigger === 'click' || trigger === 'enter' || trigger === 'contextMenu') {
380
- allow = true;
381
- break;
382
- }
374
+ if (triggersSet.has('click')) {
375
+ setInnerOpen(openHolding.current = true);
383
376
  }
384
- return allow;
385
- })();
377
+ else {
378
+ // trigger中不包含"click",则无需保持打开状态,否则会与focus冲突
379
+ openHolding.current = false;
380
+ }
381
+ }, [children?.props.onClick]);
386
382
  const onClickAway = () => {
387
383
  setInnerOpen(openHolding.current = false);
388
384
  };
@@ -413,11 +409,12 @@ exports.Popper = (0, react_1.forwardRef)(({ popperRef, anchorElement, container
413
409
  ref: (0, react_1.useCallback)((0, utils_1.cloneRef)(children.ref, anchorRef, ref), [children.ref]),
414
410
  ...hoverable && { onPointerEnter, onPointerLeave },
415
411
  ...triggersSet.has('click') && { onClick },
416
- ...triggersSet.has('focus') && { onFocus, onBlur },
412
+ // 通常点击会触发focus,因此这里需要处理点击事件
413
+ ...triggersSet.has('focus') && { onClick, onFocus, onBlur },
417
414
  ...triggersSet.has('enter') && { onKeyDown },
418
415
  ...triggersSet.has('contextMenu') && { onContextMenu }
419
416
  })
420
- : children, renderedOnce.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(clickAway_1.ClickAway, { disabled: !allowClickAway,
417
+ : children, renderedOnce.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(clickAway_1.ClickAway, { disabled: !triggersSet.has('click') && !triggersSet.has('enter') && !triggersSet.has('contextMenu'),
421
418
  // 非右键菜单不能点击anchor关闭
422
419
  targets: () => contextMenuEvent.current ? null : anchorRef.current, onClickAway: onClickAway, children: (0, jsx_runtime_1.jsx)("div", { ...props, ref: innerPopperRef, css: popper_style_1.style, className: (0, utils_1.classnames)(popper_style_1.classes.root, props?.className), style: {
423
420
  ...popperSize,
@@ -3,6 +3,9 @@ import { ModalProps } from '../modal';
3
3
  import { ReactZoomPanPinchContentRef, ReactZoomPanPinchProps } from 'react-zoom-pan-pinch';
4
4
  export interface ImagePreviewProps extends ModalProps {
5
5
  src?: string | string[];
6
+ defaultIndex?: number;
7
+ index?: number;
8
+ onIndexChange?(index: number): void;
6
9
  defaultOpen?: boolean;
7
10
  onOpenChange?(open: boolean): void;
8
11
  /** 是否渲染旋转按钮{@default true} */
@@ -1,28 +1,28 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
2
  import { forwardRef, memo, useRef, useState } from 'react';
3
3
  import { Modal } from '../modal';
4
- import { classnames, cloneRef, useControlled } from '../../utils';
4
+ import { classnames, cloneRef, toArray, useControlled } from '../../utils';
5
5
  import { classes, style } from './imagePreview.style';
6
6
  import { CloseOutlined, FullscreenOutlined, LeftOutlined, RightOutlined, RotateLeftOutlined, RotateRightOutlined, ZoomInOutlined, ZoomOutOutlined } from '@ant-design/icons';
7
7
  import { Button } from '../button';
8
8
  import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
9
9
  import { Tooltip } from '../tooltip';
10
- export const ImagePreview = memo(forwardRef(({ src = [], defaultOpen = false, open, onOpenChange, showRotate = true, showZoom = true, showClose = true, renderControl, transformWrapperProps, transformWrapperRef, ...props }, ref) => {
11
- const srcArr = Array.isArray(src) ? src : [src];
10
+ export const ImagePreview = memo(forwardRef(({ src = [], defaultIndex = 0, index, onIndexChange, defaultOpen = false, open, onOpenChange, showRotate = true, showZoom = true, showClose = true, renderControl, transformWrapperProps, transformWrapperRef, ...props }, ref) => {
11
+ const srcArr = toArray(src);
12
12
  const [innerOpen, setInnerOpen] = useControlled(defaultOpen, open, onOpenChange);
13
- const [activeIndex, setActiveIndex] = useState(0);
13
+ const [innerIndex, setInnerIndex] = useControlled(defaultIndex, index, onIndexChange);
14
14
  const innerTransformWrapperRef = useRef(null);
15
15
  const imgLoaded = () => {
16
16
  innerTransformWrapperRef.current.centerView();
17
17
  };
18
18
  const prev = (e) => {
19
19
  e.stopPropagation();
20
- setActiveIndex(o => (o - 1 + srcArr.length) % srcArr.length);
20
+ setInnerIndex(o => (o - 1 + srcArr.length) % srcArr.length);
21
21
  innerTransformWrapperRef.current?.resetTransform();
22
22
  };
23
23
  const next = (e) => {
24
24
  e.stopPropagation();
25
- setActiveIndex(o => (o + 1) % srcArr.length);
25
+ setInnerIndex(o => (o + 1) % srcArr.length);
26
26
  innerTransformWrapperRef.current?.resetTransform();
27
27
  };
28
28
  const [rotate, setRotate] = useState(0);
@@ -39,7 +39,7 @@ export const ImagePreview = memo(forwardRef(({ src = [], defaultOpen = false, op
39
39
  _jsxs(_Fragment, { children: [_jsx(Tooltip, { title: "\u65CB\u8F6C-90\u00B0", children: _jsx(Button, { ...commonControlProps, onClick: () => setRotate(rotate - 90), children: _jsx(RotateLeftOutlined, {}) }) }), _jsx(Tooltip, { title: "\u65CB\u8F6C90\u00B0", children: _jsx(Button, { ...commonControlProps, onClick: () => setRotate(rotate + 90), children: _jsx(RotateRightOutlined, {}) }) })] }), showZoom &&
40
40
  _jsxs(_Fragment, { children: [_jsx(Tooltip, { title: "\u7F29\u5C0F", children: _jsx(Button, { ...commonControlProps, onClick: () => innerTransformWrapperRef.current.zoomOut(), children: _jsx(ZoomOutOutlined, {}) }) }), _jsx(Tooltip, { title: "\u653E\u5927", children: _jsx(Button, { ...commonControlProps, onClick: () => innerTransformWrapperRef.current.zoomIn(), children: _jsx(ZoomInOutlined, {}) }) }), _jsx(Tooltip, { title: "\u9002\u5E94\u5C4F\u5E55", children: _jsx(Button, { ...commonControlProps, onClick: () => innerTransformWrapperRef.current.resetTransform(), children: _jsx(FullscreenOutlined, {}) }) })] }), showClose &&
41
41
  _jsx(Button, { ...commonControlProps, onClick: () => setInnerOpen(false), children: _jsx(CloseOutlined, {}) })] }), srcArr.length > 1 &&
42
- _jsxs(_Fragment, { children: [_jsxs("div", { className: classes.swap, children: [_jsx(Button, { ...commonControlProps, onClick: prev, children: _jsx(LeftOutlined, {}) }), _jsx(Button, { ...commonControlProps, onClick: next, children: _jsx(RightOutlined, {}) })] }), _jsxs("div", { className: classes.counter, children: [activeIndex + 1, " / ", srcArr.length] })] })] }))
42
+ _jsxs(_Fragment, { children: [_jsxs("div", { className: classes.swap, children: [_jsx(Button, { ...commonControlProps, onClick: prev, children: _jsx(LeftOutlined, {}) }), _jsx(Button, { ...commonControlProps, onClick: next, children: _jsx(RightOutlined, {}) })] }), _jsxs("div", { className: classes.counter, children: [innerIndex.current + 1, " / ", srcArr.length] })] })] }))
43
43
  }, children: _jsx(TransformWrapper, { smooth: false, ...transformWrapperProps, ref: cloneRef(transformWrapperRef, innerTransformWrapperRef), minScale: .2, onPanning: (ref, e) => {
44
44
  transformWrapperProps?.onPanning?.(ref, e);
45
45
  isPanning.current = true;
@@ -48,5 +48,5 @@ export const ImagePreview = memo(forwardRef(({ src = [], defaultOpen = false, op
48
48
  isPanning.current && setTimeout(() => isPanning.current = false);
49
49
  }, children: _jsx(TransformComponent, { wrapperClass: classes.imageWrapper, contentClass: classes.image, wrapperProps: {
50
50
  onClick: () => !isPanning.current && setInnerOpen(false)
51
- }, children: _jsx("img", { src: srcArr[activeIndex], style: { rotate: rotate + 'deg' }, onLoad: imgLoaded, alt: "" }) }) }) }));
51
+ }, children: _jsx("img", { src: srcArr[innerIndex.current], style: { rotate: rotate + 'deg' }, onLoad: imgLoaded, alt: "" }) }) }) }));
52
52
  }));
@@ -368,18 +368,14 @@ export const Popper = forwardRef(({ popperRef, anchorElement, container = docume
368
368
  // click
369
369
  const onClick = useCallback((e) => {
370
370
  children?.props.onClick?.(e);
371
- setInnerOpen(openHolding.current = true);
372
- }, [children?.props.onClick]);
373
- const allowClickAway = (() => {
374
- let allow = false;
375
- for (const trigger of triggersSet) {
376
- if (trigger === 'click' || trigger === 'enter' || trigger === 'contextMenu') {
377
- allow = true;
378
- break;
379
- }
371
+ if (triggersSet.has('click')) {
372
+ setInnerOpen(openHolding.current = true);
380
373
  }
381
- return allow;
382
- })();
374
+ else {
375
+ // trigger中不包含"click",则无需保持打开状态,否则会与focus冲突
376
+ openHolding.current = false;
377
+ }
378
+ }, [children?.props.onClick]);
383
379
  const onClickAway = () => {
384
380
  setInnerOpen(openHolding.current = false);
385
381
  };
@@ -410,11 +406,12 @@ export const Popper = forwardRef(({ popperRef, anchorElement, container = docume
410
406
  ref: useCallback(cloneRef(children.ref, anchorRef, ref), [children.ref]),
411
407
  ...hoverable && { onPointerEnter, onPointerLeave },
412
408
  ...triggersSet.has('click') && { onClick },
413
- ...triggersSet.has('focus') && { onFocus, onBlur },
409
+ // 通常点击会触发focus,因此这里需要处理点击事件
410
+ ...triggersSet.has('focus') && { onClick, onFocus, onBlur },
414
411
  ...triggersSet.has('enter') && { onKeyDown },
415
412
  ...triggersSet.has('contextMenu') && { onContextMenu }
416
413
  })
417
- : children, renderedOnce.current && createPortal(_jsx(ClickAway, { disabled: !allowClickAway,
414
+ : children, renderedOnce.current && createPortal(_jsx(ClickAway, { disabled: !triggersSet.has('click') && !triggersSet.has('enter') && !triggersSet.has('contextMenu'),
418
415
  // 非右键菜单不能点击anchor关闭
419
416
  targets: () => contextMenuEvent.current ? null : anchorRef.current, onClickAway: onClickAway, children: _jsx("div", { ...props, ref: innerPopperRef, css: style, className: classnames(classes.root, props?.className), style: {
420
417
  ...popperSize,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canlooks/can-ui",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "author": "C.CanLiang <canlooks@gmail.com>",
5
5
  "description": "My ui framework",
6
6
  "license": "MIT",