@canlooks/can-ui 0.0.67 → 0.0.68
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.
- package/dist/cjs/components/anchorList/anchorList.js +26 -20
- package/dist/cjs/components/cascade/cascade.js +2 -2
- package/dist/cjs/components/curd/curdColumnConfig.js +2 -1
- package/dist/cjs/components/dataGrid/dataGrid.js +3 -2
- package/dist/cjs/components/gallery/gallery.js +2 -2
- package/dist/cjs/components/menu/menu.js +2 -2
- package/dist/cjs/components/overlayBase/overlayBase.d.ts +3 -1
- package/dist/cjs/components/overlayBase/overlayBase.js +5 -5
- package/dist/cjs/components/popper/popper.d.ts +3 -1
- package/dist/cjs/components/popper/popper.js +6 -6
- package/dist/cjs/components/progress/progress.js +4 -2
- package/dist/cjs/components/snackbarBase/snackbarBase.d.ts +3 -2
- package/dist/cjs/components/snackbarBase/snackbarBase.js +3 -3
- package/dist/cjs/components/theme/themeVariables.d.ts +1 -0
- package/dist/cjs/components/theme/themeVariables.js +1 -0
- package/dist/cjs/components/touchRipple/index.d.ts +1 -0
- package/dist/cjs/components/touchRipple/index.js +1 -0
- package/dist/cjs/components/touchRipple/touchRipple.d.ts +6 -14
- package/dist/cjs/components/touchRipple/touchRipple.js +54 -39
- package/dist/cjs/components/touchRipple/touchRipple.style.js +25 -27
- package/dist/cjs/components/transfer/transfer.js +2 -2
- package/dist/cjs/components/transfer/transferPanel.js +2 -1
- package/dist/cjs/components/upload/upload.js +2 -2
- package/dist/cjs/components/waterfall/waterfallItem.js +1 -1
- package/dist/cjs/utils/hooks.d.ts +8 -0
- package/dist/cjs/utils/hooks.js +22 -0
- package/dist/esm/components/anchorList/anchorList.js +26 -20
- package/dist/esm/components/cascade/cascade.js +2 -2
- package/dist/esm/components/curd/curdColumnConfig.js +2 -1
- package/dist/esm/components/dataGrid/dataGrid.js +3 -2
- package/dist/esm/components/gallery/gallery.js +2 -2
- package/dist/esm/components/menu/menu.js +2 -2
- package/dist/esm/components/overlayBase/overlayBase.d.ts +3 -1
- package/dist/esm/components/overlayBase/overlayBase.js +6 -6
- package/dist/esm/components/popper/popper.d.ts +3 -1
- package/dist/esm/components/popper/popper.js +7 -7
- package/dist/esm/components/progress/progress.js +4 -2
- package/dist/esm/components/snackbarBase/snackbarBase.d.ts +3 -2
- package/dist/esm/components/snackbarBase/snackbarBase.js +4 -4
- package/dist/esm/components/theme/themeVariables.d.ts +1 -0
- package/dist/esm/components/theme/themeVariables.js +1 -0
- package/dist/esm/components/touchRipple/index.d.ts +1 -0
- package/dist/esm/components/touchRipple/index.js +1 -0
- package/dist/esm/components/touchRipple/touchRipple.d.ts +6 -14
- package/dist/esm/components/touchRipple/touchRipple.js +54 -39
- package/dist/esm/components/touchRipple/touchRipple.style.js +25 -27
- package/dist/esm/components/transfer/transfer.js +2 -2
- package/dist/esm/components/transfer/transferPanel.js +2 -1
- package/dist/esm/components/upload/upload.js +2 -2
- package/dist/esm/components/waterfall/waterfallItem.js +2 -2
- package/dist/esm/utils/hooks.d.ts +8 -0
- package/dist/esm/utils/hooks.js +21 -0
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ const waterfall_style_1 = require("./waterfall.style");
|
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
7
|
const WaterfallItem = ({ ref, onLoad, child }) => {
|
|
8
8
|
const innerRef = (0, react_1.useRef)(null);
|
|
9
|
-
(0, react_1.
|
|
9
|
+
(0, react_1.useEffect)(() => {
|
|
10
10
|
const el = innerRef.current;
|
|
11
11
|
if (!el) {
|
|
12
12
|
throw Error(`Children of <Waterfall> must expose 'ref' prop`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RefObject, Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { DefineElement } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* 获取渲染前的值
|
|
4
5
|
* @param value
|
|
@@ -48,3 +49,10 @@ export declare function useLoading<A extends any[], R>(fn: (...args: A) => R | P
|
|
|
48
49
|
(...args: A) => Promise<R>,
|
|
49
50
|
Dispatch<SetStateAction<boolean>>
|
|
50
51
|
];
|
|
52
|
+
/**
|
|
53
|
+
* 获取容器元素,通常用于`container`或`effectContainer`属性
|
|
54
|
+
* @param container
|
|
55
|
+
* @param effectContainer
|
|
56
|
+
* @param defaultContainer 默认为`document.body`
|
|
57
|
+
*/
|
|
58
|
+
export declare function useContainer<T extends HTMLElement | null>(container?: DefineElement<T>, effectContainer?: DefineElement<T>, defaultContainer?: T): RefObject<T>;
|
package/dist/cjs/utils/hooks.js
CHANGED
|
@@ -8,6 +8,7 @@ exports.useDerivedState = useDerivedState;
|
|
|
8
8
|
exports.useUnmounted = useUnmounted;
|
|
9
9
|
exports.useControlled = useControlled;
|
|
10
10
|
exports.useLoading = useLoading;
|
|
11
|
+
exports.useContainer = useContainer;
|
|
11
12
|
const react_1 = require("react");
|
|
12
13
|
const utils_1 = require("./utils");
|
|
13
14
|
/**
|
|
@@ -123,3 +124,24 @@ function useLoading(fn, referredLoading = false) {
|
|
|
123
124
|
setLoading
|
|
124
125
|
];
|
|
125
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* 获取容器元素,通常用于`container`或`effectContainer`属性
|
|
129
|
+
* @param container
|
|
130
|
+
* @param effectContainer
|
|
131
|
+
* @param defaultContainer 默认为`document.body`
|
|
132
|
+
*/
|
|
133
|
+
function useContainer(container, effectContainer, defaultContainer = document.body) {
|
|
134
|
+
const [containerEl, setContainerEl] = useDerivedState(prev => {
|
|
135
|
+
if (container) {
|
|
136
|
+
return typeof container === 'function' ? container() : container;
|
|
137
|
+
}
|
|
138
|
+
return prev || defaultContainer;
|
|
139
|
+
}, [container, defaultContainer]);
|
|
140
|
+
(0, react_1.useEffect)(() => {
|
|
141
|
+
if (effectContainer) {
|
|
142
|
+
const el = typeof effectContainer === 'function' ? effectContainer() : effectContainer;
|
|
143
|
+
setContainerEl(el);
|
|
144
|
+
}
|
|
145
|
+
}, []);
|
|
146
|
+
return containerEl;
|
|
147
|
+
}
|
|
@@ -18,10 +18,11 @@ export const AnchorList = memo(({ anchors, renderAnchorItem, indent = 24, scroll
|
|
|
18
18
|
});
|
|
19
19
|
const scrollToId = (id) => {
|
|
20
20
|
const targetEl = document.getElementById(id);
|
|
21
|
-
|
|
21
|
+
const scrollerEl = getScroller();
|
|
22
|
+
if (!targetEl || !scrollerEl) {
|
|
22
23
|
return false;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
scrollerEl.scrollTo({
|
|
25
26
|
top: targetEl.offsetTop - offset,
|
|
26
27
|
// 初始化之前无需平滑滚动
|
|
27
28
|
behavior: initialized.current ? scrollBehavior : 'instant'
|
|
@@ -50,29 +51,34 @@ export const AnchorList = memo(({ anchors, renderAnchorItem, indent = 24, scroll
|
|
|
50
51
|
* 监听滚动设置高亮
|
|
51
52
|
*/
|
|
52
53
|
const getScroller = () => {
|
|
53
|
-
|
|
54
|
+
if (scroller) {
|
|
55
|
+
return typeof scroller === 'function' ? scroller() : scroller;
|
|
56
|
+
}
|
|
57
|
+
return document.documentElement;
|
|
54
58
|
};
|
|
55
59
|
const [activeId, setActiveId] = useSyncState();
|
|
56
60
|
useEffect(() => {
|
|
57
61
|
const scrollerEl = getScroller();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
minDistance
|
|
68
|
-
|
|
62
|
+
if (scrollerEl) {
|
|
63
|
+
const scroll = () => {
|
|
64
|
+
let nearest;
|
|
65
|
+
let minDistance = Infinity;
|
|
66
|
+
const targets = anchors?.map(item => document.getElementById(item.id));
|
|
67
|
+
targets?.forEach(target => {
|
|
68
|
+
const top = target?.getBoundingClientRect().top;
|
|
69
|
+
if (typeof top === 'number') {
|
|
70
|
+
const distance = Math.abs(top - offset);
|
|
71
|
+
if (distance < minDistance) {
|
|
72
|
+
minDistance = distance;
|
|
73
|
+
nearest = target;
|
|
74
|
+
}
|
|
69
75
|
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
});
|
|
77
|
+
nearest && setActiveId(nearest.id);
|
|
78
|
+
};
|
|
79
|
+
!activeId.current && scroll();
|
|
80
|
+
return listenAllPredecessorsScroll(scrollerEl === document.documentElement ? document : scrollerEl, scroll);
|
|
81
|
+
}
|
|
76
82
|
}, [anchors, scroller, offset]);
|
|
77
83
|
const [animating, setAnimating] = useDerivedState(prev => typeof prev !== 'undefined', [activeId.current]);
|
|
78
84
|
return (_jsxs(Flex, { direction: "column", alignItems: "flex-start", ...props, css: style, className: clsx(classes.root, props.className), "data-animating": animating.current, children: [anchors?.map(item => {
|
|
@@ -16,7 +16,7 @@ const CascadeContext = createContext({});
|
|
|
16
16
|
export function useCascadeContext() {
|
|
17
17
|
return useContext(CascadeContext);
|
|
18
18
|
}
|
|
19
|
-
export const Cascade = memo(({ inputProps, defaultOpen = false, open, onOpenChange, children, loadOptions, multiple = false, showCheckbox = !!multiple, defaultValue
|
|
19
|
+
export const Cascade = memo(({ inputProps, defaultOpen = false, open, onOpenChange, children, loadOptions, multiple = false, showCheckbox = !!multiple, defaultValue, value, onChange, renderBackfill, searchable, defaultSearchValue = '', searchValue, onSearchChange, searchInputProps, popperProps, popperRef, clearable = !!multiple, integration = 'deepest',
|
|
20
20
|
// 共享属性,从OptionsBaseSharedProps继承
|
|
21
21
|
loading, options, labelKey = 'label', primaryKey = 'value', childrenKey = 'children', searchTokenKey = 'searchToken', ...props }) => {
|
|
22
22
|
/**
|
|
@@ -75,7 +75,7 @@ loading, options, labelKey = 'label', primaryKey = 'value', childrenKey = 'child
|
|
|
75
75
|
* --------------------------------------------------------------------
|
|
76
76
|
* 控制选中状态
|
|
77
77
|
*/
|
|
78
|
-
const [pathifiedValue, setPathifiedValue] = useControlled(defaultValue, value, onChange);
|
|
78
|
+
const [pathifiedValue, setPathifiedValue] = useControlled(defaultValue || [], value, onChange);
|
|
79
79
|
// 路径转单一键
|
|
80
80
|
const toStandardValue = (path) => {
|
|
81
81
|
if (!path) {
|
|
@@ -11,7 +11,8 @@ import { SortableContext } from '@dnd-kit/sortable';
|
|
|
11
11
|
import { isUnset, onDndDragEnd, useDndSensors } from '../../utils';
|
|
12
12
|
import { Icon } from '../..';
|
|
13
13
|
import { faGear } from '@fortawesome/free-solid-svg-icons/faGear';
|
|
14
|
-
export const CurdColumnConfig = memo(({ columns
|
|
14
|
+
export const CurdColumnConfig = memo(({ columns, innerVisible, setInnerVisible, setInnerOrder, }) => {
|
|
15
|
+
columns ||= [];
|
|
15
16
|
const dragEndHandler = (e) => {
|
|
16
17
|
const newColumns = onDndDragEnd(e, columns, '_key');
|
|
17
18
|
newColumns && setInnerOrder(newColumns.flatMap(col => col._key ?? []));
|
|
@@ -14,7 +14,7 @@ const DataGridContext = createContext({});
|
|
|
14
14
|
export function useDataGridContext() {
|
|
15
15
|
return useContext(DataGridContext);
|
|
16
16
|
}
|
|
17
|
-
export const DataGrid = memo(({ columns, rows, rowProps, primaryKey = 'id', childrenKey = null, defaultOrderColumn, orderColumn, defaultOrderType = 'descend', orderType, onOrderChange, selectable, relation = 'dependent', integration = 'shallowest', allowSelectAll = true, clickRowToSelect = true, selectorProps, indent = 24, renderExpandIcon, defaultExpanded
|
|
17
|
+
export const DataGrid = memo(({ columns, rows, rowProps, primaryKey = 'id', childrenKey = null, defaultOrderColumn, orderColumn, defaultOrderType = 'descend', orderType, onOrderChange, selectable, relation = 'dependent', integration = 'shallowest', allowSelectAll = true, clickRowToSelect = true, selectorProps, indent = 24, renderExpandIcon, defaultExpanded, expanded, onExpandedChange, paginatable = true, paginationProps, renderPagination, loading, emptyPlaceholder, columnResizable = false, size, bordered, striped, tableProps, multiple, defaultValue, value, onChange, ...props }) => {
|
|
18
18
|
/**
|
|
19
19
|
* ---------------------------------------------------------------
|
|
20
20
|
* 选择行
|
|
@@ -61,7 +61,7 @@ export const DataGrid = memo(({ columns, rows, rowProps, primaryKey = 'id', chil
|
|
|
61
61
|
* ---------------------------------------------------------------
|
|
62
62
|
* 展开行
|
|
63
63
|
*/
|
|
64
|
-
const [innerExpanded, setInnerExpanded] = useControlled(defaultExpanded, expanded);
|
|
64
|
+
const [innerExpanded, setInnerExpanded] = useControlled(defaultExpanded || [], expanded);
|
|
65
65
|
const expandedSet = useMemo(() => {
|
|
66
66
|
return new Set(innerExpanded.current);
|
|
67
67
|
}, [innerExpanded.current]);
|
|
@@ -79,6 +79,7 @@ export const DataGrid = memo(({ columns, rows, rowProps, primaryKey = 'id', chil
|
|
|
79
79
|
* ---------------------------------------------------------------
|
|
80
80
|
* 分页
|
|
81
81
|
*/
|
|
82
|
+
paginationProps ||= {};
|
|
82
83
|
const [innerPage, setInnerPage] = useControlled(paginationProps.defaultPage ?? 1, paginationProps.page, paginationProps.onPageChange);
|
|
83
84
|
const [innerPageSize, setInnerPageSize] = useControlled(paginationProps.defaultPageSize ?? 10, paginationProps.pageSize, paginationProps.onPageSizeChange);
|
|
84
85
|
const pageChangeHandler = (page, pageSize) => {
|
|
@@ -22,8 +22,8 @@ const commonControlProps = {
|
|
|
22
22
|
color: 'text'
|
|
23
23
|
};
|
|
24
24
|
const bounceBezier = cubicBezier(0, 0, 0, 1);
|
|
25
|
-
export const Gallery = memo(({ src
|
|
26
|
-
const srcArr = useSync(toArray(src));
|
|
25
|
+
export const Gallery = memo(({ src, defaultIndex = 0, index, onIndexChange, defaultOpen = false, open, onOpenChange, showRotation = true, showZoom = true, showClose = true, renderControl, bounceElementTranslate = 24, bounceDragDistance = 240, effectiveSpeed = 450, ...props }) => {
|
|
26
|
+
const srcArr = useSync(toArray(src || []));
|
|
27
27
|
const [innerOpen, setInnerOpen] = useControlled(defaultOpen, open, onOpenChange);
|
|
28
28
|
const close = () => {
|
|
29
29
|
setInnerOpen(false);
|
|
@@ -12,10 +12,10 @@ export function useMenuContext() {
|
|
|
12
12
|
const { size = theme.size, ellipsis = true, indent = theme.spacing[8], ...context } = useContext(MenuContext);
|
|
13
13
|
return { size, ellipsis, indent, ...context };
|
|
14
14
|
}
|
|
15
|
-
export const Menu = memo(({ items, primaryKey = 'value', labelKey = 'label', childrenKey = 'children', defaultExpanded
|
|
15
|
+
export const Menu = memo(({ items, primaryKey = 'value', labelKey = 'label', childrenKey = 'children', defaultExpanded, expanded, onExpandedChange, multiple, defaultValue, value, onChange,
|
|
16
16
|
// 以下属性传递给<MenuItem/>
|
|
17
17
|
size = 'large', showCheckbox, ellipsis, indent, ...props }) => {
|
|
18
|
-
const [innerExpanded, setInnerExpanded] = useControlled(defaultExpanded, expanded);
|
|
18
|
+
const [innerExpanded, setInnerExpanded] = useControlled(defaultExpanded || [], expanded);
|
|
19
19
|
const expandedSet = useMemo(() => {
|
|
20
20
|
return new Set(innerExpanded.current);
|
|
21
21
|
}, [innerExpanded.current]);
|
|
@@ -4,6 +4,8 @@ import { TransitionBaseProps } from '../transitionBase';
|
|
|
4
4
|
export interface OverlayBaseProps extends DivProps {
|
|
5
5
|
/** 模态的容器元素,默认为document.body */
|
|
6
6
|
container?: DefineElement<HTMLElement>;
|
|
7
|
+
/** 同{@link container},但会在useEffect后取值,且只会执行一次 */
|
|
8
|
+
effectContainer?: DefineElement<HTMLElement>;
|
|
7
9
|
/**
|
|
8
10
|
* @enum {true} 跟随父组件强制渲染
|
|
9
11
|
* @enum {false} 打开时渲染,关闭后销毁
|
|
@@ -22,4 +24,4 @@ export interface OverlayBaseProps extends DivProps {
|
|
|
22
24
|
removeFocusOnOpen?: boolean;
|
|
23
25
|
}
|
|
24
26
|
export declare const overlayBaseTransitionDuration = 300;
|
|
25
|
-
export declare function OverlayBase({ container, forceRender, open, onMaskClick, singleLayer, onOpened, onClosed, maskProps, removeFocusOnOpen, ...props }: OverlayBaseProps): false | React.ReactPortal;
|
|
27
|
+
export declare function OverlayBase({ container, effectContainer, forceRender, open, onMaskClick, singleLayer, onOpened, onClosed, maskProps, removeFocusOnOpen, ...props }: OverlayBaseProps): false | React.ReactPortal;
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
3
|
import { classes, style } from './overlayBase.style';
|
|
4
|
-
import { clsx, useDerivedState } from '../../utils';
|
|
4
|
+
import { clsx, useContainer, useDerivedState } from '../../utils';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
6
6
|
import { Fade } from '../transitionBase';
|
|
7
7
|
export const overlayBaseTransitionDuration = 300;
|
|
8
|
-
export function OverlayBase({ container, forceRender, open, onMaskClick, singleLayer, onOpened, onClosed, maskProps, removeFocusOnOpen = true, ...props }) {
|
|
8
|
+
export function OverlayBase({ container, effectContainer, forceRender, open, onMaskClick, singleLayer, onOpened, onClosed, maskProps, removeFocusOnOpen = true, ...props }) {
|
|
9
9
|
const [shouldRender, setShouldRender] = useDerivedState((prev = false) => {
|
|
10
10
|
if (open) {
|
|
11
11
|
return true;
|
|
12
12
|
}
|
|
13
13
|
return forceRender === true || prev;
|
|
14
14
|
}, [open, forceRender]);
|
|
15
|
-
const containerEl = (
|
|
15
|
+
const containerEl = useContainer(container, effectContainer);
|
|
16
16
|
useEffect(() => {
|
|
17
17
|
if (!open) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
removeFocusOnOpen && document.activeElement?.blur?.();
|
|
21
|
-
containerEl.style.overflow = 'hidden';
|
|
21
|
+
containerEl.current.style.overflow = 'hidden';
|
|
22
22
|
return () => {
|
|
23
|
-
containerEl.style.overflow = '';
|
|
23
|
+
containerEl.current.style.overflow = '';
|
|
24
24
|
};
|
|
25
25
|
}, [open]);
|
|
26
26
|
const clickHandler = (e) => {
|
|
@@ -36,5 +36,5 @@ export function OverlayBase({ container, forceRender, open, onMaskClick, singleL
|
|
|
36
36
|
onClosed?.();
|
|
37
37
|
forceRender === false && setShouldRender(false);
|
|
38
38
|
};
|
|
39
|
-
return shouldRender.current && createPortal(_jsxs("div", { ...props, css: style, className: clsx(classes.root, props.className), "data-open": open, "data-custom-container": containerEl !== document.body, children: [_jsx(Fade, { timeout: overlayBaseTransitionDuration, ...maskProps, in: open, className: clsx(classes.mask, maskProps?.className), onClick: clickHandler, onEntered: onEntered, onExited: onExited }), props.children] }), containerEl);
|
|
39
|
+
return shouldRender.current && createPortal(_jsxs("div", { ...props, css: style, className: clsx(classes.root, props.className), "data-open": open, "data-custom-container": containerEl.current !== document.body, children: [_jsx(Fade, { timeout: overlayBaseTransitionDuration, ...maskProps, in: open, className: clsx(classes.mask, maskProps?.className), onClick: clickHandler, onEntered: onEntered, onExited: onExited }), props.children] }), containerEl.current);
|
|
40
40
|
}
|
|
@@ -7,6 +7,8 @@ export interface PopperProps extends Omit<DivProps, 'content' | 'children'> {
|
|
|
7
7
|
anchorElement?: DefineElement<HTMLElement>;
|
|
8
8
|
/** 弹框渲染的容器元素,默认为{@link document.body} */
|
|
9
9
|
container?: DefineElement<HTMLElement>;
|
|
10
|
+
/** 同{@link container},但会在useEffect后取值,且只会执行一次 */
|
|
11
|
+
effectContainer?: DefineElement<HTMLElement>;
|
|
10
12
|
/** 汽泡里的内容 */
|
|
11
13
|
content?: ReactNode;
|
|
12
14
|
/** 弹框偏离元素的距离 */
|
|
@@ -46,4 +48,4 @@ export interface PopperRef extends HTMLDivElement {
|
|
|
46
48
|
openAnimation?: boolean;
|
|
47
49
|
}, beforeOpen?: () => void): void;
|
|
48
50
|
}
|
|
49
|
-
export declare function Popper({ ref, popperRef, anchorElement, container, content, offset, trigger, placement, variant, sizeAdaptable, mouseEnterDelay, mouseLeaveDelay, defaultOpen, open, onOpenChange, onOpenChangeEnd, disabled, autoClose, forceRender, children, ...props }: PopperProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
51
|
+
export declare function Popper({ ref, popperRef, anchorElement, container, effectContainer, content, offset, trigger, placement, variant, sizeAdaptable, mouseEnterDelay, mouseLeaveDelay, defaultOpen, open, onOpenChange, onOpenChangeEnd, disabled, autoClose, forceRender, children, ...props }: PopperProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
2
|
import { cloneElement, isValidElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
|
-
import { clsx, cloneRef, isElementVisibleCompletely, listenAllPredecessorsScroll, toArray, useControlled, useDerivedState, useForceUpdate, useSync, useSyncState, useUnmounted } from '../../utils';
|
|
4
|
+
import { clsx, cloneRef, isElementVisibleCompletely, listenAllPredecessorsScroll, toArray, useControlled, useDerivedState, useForceUpdate, useSync, useSyncState, useUnmounted, useContainer } from '../../utils';
|
|
5
5
|
import { ClickAway } from '../clickAway';
|
|
6
6
|
import { classes, style } from './popper.style';
|
|
7
7
|
import { PopperContext, usePopperContext } from './popperContext';
|
|
@@ -19,7 +19,7 @@ const getAttemptOrder = (placement) => {
|
|
|
19
19
|
}
|
|
20
20
|
return order;
|
|
21
21
|
};
|
|
22
|
-
export function Popper({ ref, popperRef, anchorElement, container = document.body, content, offset, trigger = 'hover', placement = 'top', variant = 'zoom', sizeAdaptable = variant === 'collapse', mouseEnterDelay = 100, mouseLeaveDelay = 150, defaultOpen = false, open, onOpenChange, onOpenChangeEnd, disabled, autoClose = false, forceRender, children, ...props }) {
|
|
22
|
+
export function Popper({ ref, popperRef, anchorElement, container = document.body, effectContainer, content, offset, trigger = 'hover', placement = 'top', variant = 'zoom', sizeAdaptable = variant === 'collapse', mouseEnterDelay = 100, mouseLeaveDelay = 150, defaultOpen = false, open, onOpenChange, onOpenChangeEnd, disabled, autoClose = false, forceRender, children, ...props }) {
|
|
23
23
|
const { spacing } = useTheme();
|
|
24
24
|
offset ??= spacing[2];
|
|
25
25
|
useImperativeHandle(popperRef, () => {
|
|
@@ -101,14 +101,14 @@ export function Popper({ ref, popperRef, anchorElement, container = document.bod
|
|
|
101
101
|
const getAnchorElement = () => {
|
|
102
102
|
return anchorRef.current || (typeof syncAnchorElement.current === 'function' ? syncAnchorElement.current() : syncAnchorElement.current);
|
|
103
103
|
};
|
|
104
|
-
const
|
|
104
|
+
const containerEl = useContainer(container, effectContainer);
|
|
105
105
|
const innerPopperRef = useRef(null);
|
|
106
106
|
const [popperBounding, setPopperBounding] = useState();
|
|
107
107
|
const [openNextFrame, setOpenNextFrame] = useDerivedState(!innerOpen.current, [innerOpen.current, contextMenuEvent.current]);
|
|
108
108
|
const placeA = useRef(void 0);
|
|
109
109
|
const placeB = useRef(void 0);
|
|
110
110
|
const fitPosition = (options, beforeOpen) => {
|
|
111
|
-
const containerRect =
|
|
111
|
+
const containerRect = containerEl.current.getBoundingClientRect();
|
|
112
112
|
const popperEl = innerPopperRef.current;
|
|
113
113
|
let { offsetWidth: popperWidth, offsetHeight: popperHeight } = popperEl;
|
|
114
114
|
let pA, pB;
|
|
@@ -184,7 +184,7 @@ export function Popper({ ref, popperRef, anchorElement, container = document.bod
|
|
|
184
184
|
}
|
|
185
185
|
popperEl.style.left = left + 'px';
|
|
186
186
|
popperEl.style.top = top + 'px';
|
|
187
|
-
return isElementVisibleCompletely(popperEl,
|
|
187
|
+
return isElementVisibleCompletely(popperEl, containerEl.current === document.body ? void 0 : containerEl.current);
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
else {
|
|
@@ -255,7 +255,7 @@ export function Popper({ ref, popperRef, anchorElement, container = document.bod
|
|
|
255
255
|
}
|
|
256
256
|
popperEl.style.left = left + 'px';
|
|
257
257
|
popperEl.style.top = top + 'px';
|
|
258
|
-
return isElementVisibleCompletely(popperEl,
|
|
258
|
+
return isElementVisibleCompletely(popperEl, containerEl.current === document.body ? void 0 : containerEl.current);
|
|
259
259
|
};
|
|
260
260
|
}
|
|
261
261
|
if (options?.forcePlacement) {
|
|
@@ -499,5 +499,5 @@ export function Popper({ ref, popperRef, anchorElement, container = document.bod
|
|
|
499
499
|
transform: 'scale(1)'
|
|
500
500
|
},
|
|
501
501
|
...props.style
|
|
502
|
-
}, "data-open": innerOpen.current, "data-variant": variant, "data-place-a": placeA.current, "data-place-b": placeB.current, onTransitionEnd: onTransitionEnd, children: _jsx(PopperContext, { value: contextValue, children: content }) }) }),
|
|
502
|
+
}, "data-open": innerOpen.current, "data-variant": variant, "data-place-a": placeA.current, "data-place-b": placeB.current, onTransitionEnd: onTransitionEnd, children: _jsx(PopperContext, { value: contextValue, children: content }) }) }), containerEl.current)] }));
|
|
503
503
|
}
|
|
@@ -7,7 +7,9 @@ import { css, keyframes } from '@emotion/react';
|
|
|
7
7
|
import { Icon } from '../..';
|
|
8
8
|
import { faCircleCheck } from '@fortawesome/free-solid-svg-icons/faCircleCheck';
|
|
9
9
|
import { faCircleXmark } from '@fortawesome/free-solid-svg-icons/faCircleXmark';
|
|
10
|
-
export const Progress = memo(({ showInfo = true, renderInfo, color
|
|
10
|
+
export const Progress = memo(({ showInfo = true, renderInfo, color, status = 'default', variant = 'linear', gapDegree = 90, size = 60, indeterminate = false, barWidth = 4, strokeLinecap = variant === 'gauge' ? 'butt' : 'round', value = 0, ...props }) => {
|
|
11
|
+
const isColorSpecified = !!color;
|
|
12
|
+
color ??= 'primary';
|
|
11
13
|
const { colors: { success, error } } = useTheme();
|
|
12
14
|
const isSucceed = status === 'success' || (status !== 'error' && value === 100 && variant !== 'gauge');
|
|
13
15
|
const renderInfoFn = () => {
|
|
@@ -52,7 +54,7 @@ export const Progress = memo(({ showInfo = true, renderInfo, color = 'primary',
|
|
|
52
54
|
}
|
|
53
55
|
return;
|
|
54
56
|
}, [indeterminate, variant, strokeLinecap, size, barWidth]);
|
|
55
|
-
return (_jsx("div", { ...props, css: useStyle({ color: color || 'primary', variant }), className: clsx(classes.root, props.className), "data-variant": variant, "data-indeterminate": indeterminate, "data-processing": value < 100 && status === 'processing', "data-success": isSucceed, "data-error": status === 'error', children: variant === 'linear'
|
|
57
|
+
return (_jsx("div", { ...props, css: useStyle({ color: color || 'primary', variant }), className: clsx(classes.root, props.className), "data-variant": variant, "data-indeterminate": indeterminate, "data-processing": value < 100 && status === 'processing', "data-success": isColorSpecified ? void 0 : isSucceed, "data-error": isColorSpecified ? void 0 : status === 'error', children: variant === 'linear'
|
|
56
58
|
? _jsxs(_Fragment, { children: [_jsx("div", { className: classes.track, style: {
|
|
57
59
|
height: barWidth,
|
|
58
60
|
...props.style
|
|
@@ -24,11 +24,12 @@ export declare class SnackbarBaseMethods<P extends SnackbarBaseProps = SnackbarB
|
|
|
24
24
|
error(content: ReactNode): Promise<void>;
|
|
25
25
|
error(props: P): Promise<void>;
|
|
26
26
|
}
|
|
27
|
-
export declare const SnackbarBase: React.MemoExoticComponent<({ methods, useTo, max, container }: {
|
|
27
|
+
export declare const SnackbarBase: React.MemoExoticComponent<({ methods, useTo, max, container, effectContainer }: {
|
|
28
28
|
methods: SnackbarBaseMethods;
|
|
29
29
|
useTo: "message" | "notification";
|
|
30
30
|
max?: number;
|
|
31
|
-
container?: DefineElement
|
|
31
|
+
container?: DefineElement<HTMLElement>;
|
|
32
|
+
effectContainer?: DefineElement<HTMLElement>;
|
|
32
33
|
}) => React.ReactPortal>;
|
|
33
34
|
interface SnackbarBaseItemProps extends Omit<SnackbarBaseProps, 'duration' | 'onAutoClose'> {
|
|
34
35
|
id: string;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
|
2
2
|
import { createElement as _createElement } from "@emotion/react";
|
|
3
3
|
import { isValidElement, memo, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { Collapse, Slide } from '../transitionBase';
|
|
5
|
-
import { clsx, getEasyID, useColor } from '../../utils';
|
|
5
|
+
import { clsx, getEasyID, useColor, useContainer } from '../../utils';
|
|
6
6
|
import { classes, style } from './snackbarBase.style';
|
|
7
7
|
import { TransitionGroup } from 'react-transition-group';
|
|
8
8
|
import { StatusIcon, statusMapToIconDefinition } from '../status';
|
|
@@ -33,7 +33,7 @@ const placementToIndex = {
|
|
|
33
33
|
bottomRight: 5,
|
|
34
34
|
rightBottom: 5
|
|
35
35
|
};
|
|
36
|
-
export const SnackbarBase = memo(({ methods, useTo, max = useTo === 'message' ? 5 : 4, container }) => {
|
|
36
|
+
export const SnackbarBase = memo(({ methods, useTo, max = useTo === 'message' ? 5 : 4, container, effectContainer }) => {
|
|
37
37
|
const [stacks, setStacks] = useState([]);
|
|
38
38
|
const timers = useRef([]);
|
|
39
39
|
useEffect(() => () => {
|
|
@@ -81,10 +81,10 @@ export const SnackbarBase = memo(({ methods, useTo, max = useTo === 'message' ?
|
|
|
81
81
|
methods.warning = defineMethod('warning');
|
|
82
82
|
methods.error = defineMethod('error');
|
|
83
83
|
const css = style();
|
|
84
|
-
const containerEl = (
|
|
84
|
+
const containerEl = useContainer(container, effectContainer);
|
|
85
85
|
return createPortal(stacks.flatMap((stack, i) => stack
|
|
86
86
|
? _jsx(TransitionGroup, { css: css, className: classes.root, "data-place": i, "data-use-to": useTo, children: stack.map(p => _createElement(SnackbarBaseItem, { ...p, key: p.id })) }, i)
|
|
87
|
-
: []), containerEl);
|
|
87
|
+
: []), containerEl.current);
|
|
88
88
|
});
|
|
89
89
|
/**
|
|
90
90
|
* ----------------------------------------------------------------------
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export interface TouchRippleProps extends Omit<DivProps, 'children'> {
|
|
1
|
+
import { ColorPropsValue, DefineElement, DivProps } from '../../types';
|
|
2
|
+
export interface TouchRippleOverlayProps extends DivProps {
|
|
4
3
|
color?: ColorPropsValue;
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/** 容器元素,默认为该组件元素的父元素 */
|
|
5
|
+
container?: DefineElement<HTMLElement>;
|
|
6
|
+
effectContainer?: DefineElement<HTMLElement>;
|
|
7
7
|
}
|
|
8
|
-
export declare const TouchRipple: {
|
|
9
|
-
(props: TouchRippleProps): ReactElement;
|
|
10
|
-
Ripple: typeof Ripple;
|
|
11
|
-
};
|
|
12
|
-
interface RippleProps extends DivProps {
|
|
13
|
-
color?: ColorPropsValue;
|
|
14
|
-
}
|
|
15
|
-
export declare const Ripple: import("react").MemoExoticComponent<({ ref, color, ...props }: RippleProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
16
|
-
export {};
|
|
8
|
+
export declare const TouchRipple: import("react").MemoExoticComponent<({ color, container, effectContainer, ...props }: TouchRippleOverlayProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
@@ -1,54 +1,69 @@
|
|
|
1
1
|
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { memo, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { cloneRef, clsx, useContainer } from '../../utils';
|
|
3
5
|
import { classes, useStyle } from './touchRipple.style';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
key: getEasyID('touch-ripple'),
|
|
25
|
-
r: Math.sqrt(wrapper.clientWidth ** 2 + wrapper.clientHeight ** 2),
|
|
26
|
-
left: e.offsetX,
|
|
27
|
-
top: e.offsetY,
|
|
6
|
+
export const TouchRipple = memo(({ color = 'primary', container, effectContainer, ...props }) => {
|
|
7
|
+
const ref = useRef(null);
|
|
8
|
+
const [ripples, setRipples] = useState(new Map());
|
|
9
|
+
const incrementKey = useRef(0);
|
|
10
|
+
const containerEl = useContainer(container, effectContainer, null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const parentElement = containerEl.current ?? ref.current.parentElement;
|
|
13
|
+
if (parentElement) {
|
|
14
|
+
const pointerDown = ({ offsetX, offsetY }) => {
|
|
15
|
+
const maxWidth = Math.max(parentElement.clientWidth - offsetX, offsetX);
|
|
16
|
+
const maxHeight = Math.max(parentElement.clientHeight - offsetY, offsetY);
|
|
17
|
+
setRipples(o => {
|
|
18
|
+
const r = new Map(o);
|
|
19
|
+
const key = ++incrementKey.current;
|
|
20
|
+
r.set(key, {
|
|
21
|
+
key,
|
|
22
|
+
diameter: Math.sqrt(maxWidth ** 2 + maxHeight ** 2) * 2,
|
|
23
|
+
left: offsetX,
|
|
24
|
+
top: offsetY,
|
|
28
25
|
leaving: false
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
});
|
|
27
|
+
return r;
|
|
28
|
+
});
|
|
29
|
+
parentElement.addEventListener('pointerup', leave);
|
|
30
|
+
parentElement.addEventListener('pointerleave', leave);
|
|
33
31
|
};
|
|
34
32
|
const leave = () => {
|
|
35
|
-
setRipples(o =>
|
|
33
|
+
setRipples(o => {
|
|
34
|
+
const r = new Map(o);
|
|
35
|
+
r.forEach(v => v.leaving = true);
|
|
36
|
+
return r;
|
|
37
|
+
});
|
|
36
38
|
removeLeaveListener();
|
|
37
39
|
};
|
|
38
|
-
wrapper.addEventListener('pointerdown', pointerDown);
|
|
39
40
|
const removeLeaveListener = () => {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
parentElement.removeEventListener('pointerup', leave);
|
|
42
|
+
parentElement.removeEventListener('pointerleave', leave);
|
|
42
43
|
};
|
|
44
|
+
parentElement.addEventListener('pointerdown', pointerDown);
|
|
43
45
|
return () => {
|
|
44
|
-
|
|
46
|
+
parentElement.removeEventListener('pointerdown', pointerDown);
|
|
45
47
|
removeLeaveListener();
|
|
46
48
|
};
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
}, [containerEl.current]);
|
|
51
|
+
const leftHandler = (key) => {
|
|
52
|
+
setRipples(o => {
|
|
53
|
+
const r = new Map(o);
|
|
54
|
+
r.delete(key);
|
|
55
|
+
if (!r.size) {
|
|
56
|
+
incrementKey.current = 0;
|
|
57
|
+
}
|
|
58
|
+
return r;
|
|
59
|
+
});
|
|
52
60
|
};
|
|
53
|
-
|
|
61
|
+
const children = (_jsx("div", { ...props, ref: cloneRef(ref, props.ref), css: useStyle({ color }), className: clsx(classes.root, props.className), children: ripples.values().toArray().map(({ key, diameter, left, top, leaving }) => _jsx("div", { className: classes.ripple, style: {
|
|
62
|
+
width: diameter,
|
|
63
|
+
height: diameter,
|
|
64
|
+
left, top
|
|
65
|
+
}, "data-leaving": leaving, onTransitionEnd: () => leftHandler(key) }, key)) }));
|
|
66
|
+
return containerEl.current
|
|
67
|
+
? createPortal(children, containerEl.current)
|
|
68
|
+
: children;
|
|
54
69
|
});
|