@canlooks/can-ui 0.0.112 → 0.0.114
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/accordion/accordion.js +2 -2
- package/dist/cjs/components/app/app.js +2 -2
- package/dist/cjs/components/clickAway/clickAway.d.ts +3 -3
- package/dist/cjs/components/icon/icon.d.ts +3 -1
- package/dist/cjs/components/overlayBase/overlayBase.d.ts +1 -1
- package/dist/cjs/components/overlayBase/overlayBase.js +1 -1
- package/dist/cjs/components/popper/popper.js +2 -2
- package/dist/cjs/components/snackbarBase/snackbarBase.d.ts +1 -1
- package/dist/cjs/components/snackbarBase/snackbarBase.js +1 -1
- package/dist/cjs/components/status/status.d.ts +9 -9
- package/dist/cjs/components/status/status.js +9 -13
- package/dist/cjs/utils/hooks.d.ts +5 -1
- package/dist/cjs/utils/hooks.js +25 -6
- package/dist/esm/components/accordion/accordion.js +1 -1
- package/dist/esm/components/app/app.js +4 -4
- package/dist/esm/components/clickAway/clickAway.d.ts +3 -3
- package/dist/esm/components/icon/icon.d.ts +3 -1
- package/dist/esm/components/overlayBase/overlayBase.d.ts +1 -1
- package/dist/esm/components/overlayBase/overlayBase.js +1 -1
- package/dist/esm/components/popper/popper.js +2 -2
- package/dist/esm/components/snackbarBase/snackbarBase.d.ts +1 -1
- package/dist/esm/components/snackbarBase/snackbarBase.js +1 -1
- package/dist/esm/components/status/status.d.ts +9 -9
- package/dist/esm/components/status/status.js +3 -7
- package/dist/esm/utils/hooks.d.ts +5 -1
- package/dist/esm/utils/hooks.js +24 -6
- package/package.json +21 -21
|
@@ -7,7 +7,7 @@ const utils_1 = require("../../utils");
|
|
|
7
7
|
const theme_1 = require("../theme");
|
|
8
8
|
const transitionBase_1 = require("../transitionBase");
|
|
9
9
|
const icon_1 = require("../icon");
|
|
10
|
-
const
|
|
10
|
+
const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
|
|
11
11
|
function Accordion({ size, title, prefix, suffix, expandIcon, defaultExpanded = false, expanded, onExpandedChange, readOnly, disabled, ...props }) {
|
|
12
12
|
const theme = (0, theme_1.useTheme)();
|
|
13
13
|
size ??= theme.size;
|
|
@@ -17,7 +17,7 @@ function Accordion({ size, title, prefix, suffix, expandIcon, defaultExpanded =
|
|
|
17
17
|
};
|
|
18
18
|
const renderExpandIcon = () => {
|
|
19
19
|
if (!expandIcon) {
|
|
20
|
-
return (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon:
|
|
20
|
+
return (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: free_solid_svg_icons_1.faCaretRight, className: accordion_style_1.classes.expandIcon });
|
|
21
21
|
}
|
|
22
22
|
if (typeof expandIcon === 'function') {
|
|
23
23
|
return expandIcon(innerExpanded.current);
|
|
@@ -27,12 +27,12 @@ exports.App = (({ theme, ...props }) => {
|
|
|
27
27
|
return ((0, jsx_runtime_1.jsx)(globalEventDelegation_1.GlobalEventDelegation, { children: (0, jsx_runtime_1.jsx)(theme_1.ThemeProvider, { theme: theme, children: (0, jsx_runtime_1.jsx)(InnerApp, { ...props }) }) }));
|
|
28
28
|
});
|
|
29
29
|
function InnerApp({ component: Component = 'div', theme, children, fill = true, ...props }) {
|
|
30
|
-
const appValue = (0,
|
|
30
|
+
const appValue = (0, utils_1.useExternalClass)(() => ({
|
|
31
31
|
dialog: exports.App.dialog = new appDialog_1.AppDialogMethods(),
|
|
32
32
|
message: exports.App.message = new appMessage_1.AppMessageMethods(),
|
|
33
33
|
notification: exports.App.notification = new appNotification_1.AppNotificationMethods(),
|
|
34
34
|
actionSheet: exports.App.actionSheet = new appActionSheet_1.AppActionSheetMethods()
|
|
35
|
-
})
|
|
35
|
+
}));
|
|
36
36
|
return ((0, jsx_runtime_1.jsxs)(AppContext, { value: appValue, children: [Component
|
|
37
37
|
? (0, jsx_runtime_1.jsx)(Component, { ...props, css: [
|
|
38
38
|
app_style_1.style,
|
|
@@ -37,7 +37,7 @@ export declare function ClickAway({ ref, container, eventType, onClickAway, disa
|
|
|
37
37
|
title: string;
|
|
38
38
|
translate: "yes" | "no";
|
|
39
39
|
radioGroup: string;
|
|
40
|
-
role: "article" | "button" | "dialog" | "figure" | "form" | "img" | "link" | "main" | "menu" | "menuitem" | "option" | "search" | "table" | "switch" | "status" | (string & {}) | "none" | "checkbox" | "listbox" | "radio" | "region" | "cell" | "grid" | "row" | "listitem" | "menubar" | "progressbar" | "separator" | "tab" | "tabpanel" | "toolbar" | "tooltip" | "treeitem" | "scrollbar" | "alert" | "alertdialog" | "application" | "banner" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "directory" | "document" | "feed" | "gridcell" | "group" | "heading" | "list" | "log" | "marquee" | "
|
|
40
|
+
role: "article" | "button" | "dialog" | "figure" | "form" | "img" | "link" | "main" | "menu" | "menuitem" | "option" | "search" | "table" | "switch" | "status" | (string & {}) | "none" | "checkbox" | "listbox" | "radio" | "region" | "cell" | "grid" | "row" | "math" | "listitem" | "menubar" | "progressbar" | "separator" | "tab" | "tabpanel" | "toolbar" | "tooltip" | "treeitem" | "scrollbar" | "alert" | "alertdialog" | "application" | "banner" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "directory" | "document" | "feed" | "gridcell" | "group" | "heading" | "list" | "log" | "marquee" | "menuitemcheckbox" | "menuitemradio" | "navigation" | "note" | "presentation" | "radiogroup" | "rowgroup" | "rowheader" | "searchbox" | "slider" | "spinbutton" | "tablist" | "term" | "textbox" | "timer" | "tree" | "treegrid";
|
|
41
41
|
about: string;
|
|
42
42
|
content: string;
|
|
43
43
|
datatype: string;
|
|
@@ -60,7 +60,7 @@ export declare function ClickAway({ ref, container, eventType, onClickAway, disa
|
|
|
60
60
|
results: number;
|
|
61
61
|
security: string;
|
|
62
62
|
unselectable: "off" | "on";
|
|
63
|
-
popover: "" | "auto" | "manual";
|
|
63
|
+
popover: "" | "auto" | "manual" | "hint";
|
|
64
64
|
popoverTargetAction: "hide" | "show" | "toggle";
|
|
65
65
|
popoverTarget: string;
|
|
66
66
|
inert: boolean;
|
|
@@ -70,7 +70,7 @@ export declare function ClickAway({ ref, container, eventType, onClickAway, disa
|
|
|
70
70
|
part: string;
|
|
71
71
|
"aria-activedescendant": string;
|
|
72
72
|
"aria-atomic": boolean | "false" | "true";
|
|
73
|
-
"aria-autocomplete": "
|
|
73
|
+
"aria-autocomplete": "none" | "both" | "inline" | "list";
|
|
74
74
|
"aria-braillelabel": string;
|
|
75
75
|
"aria-brailleroledescription": string;
|
|
76
76
|
"aria-busy": boolean | "false" | "true";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
|
|
2
2
|
import { ColorPropsValue } from '../../types';
|
|
3
|
-
|
|
3
|
+
import { IconDefinition } from '@fortawesome/free-brands-svg-icons';
|
|
4
|
+
export interface IconProps extends Omit<FontAwesomeIconProps, 'color' | 'icon'> {
|
|
4
5
|
color?: ColorPropsValue;
|
|
6
|
+
icon: FontAwesomeIconProps['icon'] | IconDefinition;
|
|
5
7
|
}
|
|
6
8
|
export declare function Icon({ color, ...props }: IconProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -24,4 +24,4 @@ export interface OverlayBaseProps extends DivProps {
|
|
|
24
24
|
removeFocusOnOpen?: boolean;
|
|
25
25
|
}
|
|
26
26
|
export declare const overlayBaseTransitionDuration = 300;
|
|
27
|
-
export declare function OverlayBase({ container, effectContainer, 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 | null;
|
|
@@ -37,7 +37,7 @@ function OverlayBase({ container, effectContainer, forceRender, open, onMaskClic
|
|
|
37
37
|
onClosed?.();
|
|
38
38
|
forceRender === false && setShouldRender(false);
|
|
39
39
|
};
|
|
40
|
-
return shouldRender.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsxs)("div", { ...props, css: overlayBase_style_1.style, className: (0, utils_1.clsx)(overlayBase_style_1.classes.root, props.className), "data-open": open, "data-custom-container": containerEl.current !== document.body, children: [(0, jsx_runtime_1.jsx)(transitionBase_1.Fade, { timeout: exports.overlayBaseTransitionDuration, ...(0, utils_1.mergeComponentProps)(maskProps, {
|
|
40
|
+
return shouldRender.current && containerEl.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsxs)("div", { ...props, css: overlayBase_style_1.style, className: (0, utils_1.clsx)(overlayBase_style_1.classes.root, props.className), "data-open": open, "data-custom-container": containerEl.current !== document.body, children: [(0, jsx_runtime_1.jsx)(transitionBase_1.Fade, { timeout: exports.overlayBaseTransitionDuration, ...(0, utils_1.mergeComponentProps)(maskProps, {
|
|
41
41
|
in: open,
|
|
42
42
|
className: overlayBase_style_1.classes.mask,
|
|
43
43
|
onClick,
|
|
@@ -22,7 +22,7 @@ const getAttemptOrder = (placement) => {
|
|
|
22
22
|
}
|
|
23
23
|
return order;
|
|
24
24
|
};
|
|
25
|
-
function Popper({ ref, popperRef, anchorElement, container
|
|
25
|
+
function Popper({ ref, popperRef, anchorElement, container, effectContainer, content, offset, trigger = 'hover', clickToClose, placement = 'top', variant = 'zoom', sizeAdaptable = variant === 'collapse', mouseEnterDelay = 150, mouseLeaveDelay = 150, defaultOpen = false, open, onOpenChange, onOpenChangeEnd, disabled, autoClose = false, forceRender, children, ...props }) {
|
|
26
26
|
const { spacing } = (0, theme_1.useTheme)();
|
|
27
27
|
offset ??= spacing[2];
|
|
28
28
|
(0, react_1.useImperativeHandle)(popperRef, () => {
|
|
@@ -537,7 +537,7 @@ function Popper({ ref, popperRef, anchorElement, container = document.body, effe
|
|
|
537
537
|
? (0, react_1.cloneElement)(children, {
|
|
538
538
|
ref: childRef
|
|
539
539
|
})
|
|
540
|
-
: children, renderedOnce.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(clickAway_1.ClickAway, { disabled: !clickable && !enterable && !contextMenuable,
|
|
540
|
+
: children, renderedOnce.current && containerEl.current && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(clickAway_1.ClickAway, { disabled: !clickable && !enterable && !contextMenuable,
|
|
541
541
|
// 右键菜单点击anchor需要关闭弹框
|
|
542
542
|
targets: () => contextMenuEvent.current ? void 0 : getAnchorElement(), onClickAway: onClickAway, children: (0, jsx_runtime_1.jsx)("div", { ...props, ref: innerPopperRef, css: popper_style_1.style, className: (0, utils_1.clsx)(popper_style_1.classes.root, props.className), style: {
|
|
543
543
|
...popperBounding,
|
|
@@ -30,7 +30,7 @@ export declare const SnackbarBase: React.MemoExoticComponent<({ methods, useTo,
|
|
|
30
30
|
max?: number;
|
|
31
31
|
container?: DefineElement<HTMLElement>;
|
|
32
32
|
effectContainer?: DefineElement<HTMLElement>;
|
|
33
|
-
}) => React.ReactPortal>;
|
|
33
|
+
}) => React.ReactPortal | null>;
|
|
34
34
|
interface SnackbarBaseItemProps extends Omit<SnackbarBaseProps, 'duration' | 'onAutoClose'> {
|
|
35
35
|
id: string;
|
|
36
36
|
type: keyof SnackbarBaseMethods;
|
|
@@ -86,7 +86,7 @@ exports.SnackbarBase = (0, react_2.memo)(({ methods, useTo, max = useTo === 'mes
|
|
|
86
86
|
methods.error = defineMethod('error');
|
|
87
87
|
const css = (0, snackbarBase_style_1.style)();
|
|
88
88
|
const containerEl = (0, utils_1.useContainer)(container, effectContainer);
|
|
89
|
-
return (0, react_dom_1.createPortal)(stacks.flatMap((stack, i) => stack
|
|
89
|
+
return containerEl.current && (0, react_dom_1.createPortal)(stacks.flatMap((stack, i) => stack
|
|
90
90
|
? (0, jsx_runtime_1.jsx)(react_transition_group_1.TransitionGroup, { css: css, className: snackbarBase_style_1.classes.root, "data-place": i, "data-use-to": useTo, children: stack.map(p => (0, react_1.createElement)(exports.SnackbarBaseItem, { ...p, key: p.id })) }, i)
|
|
91
91
|
: []), containerEl.current);
|
|
92
92
|
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { DivProps, Status as IStatus } from '../../types';
|
|
3
|
-
import {
|
|
3
|
+
import { IconProps } from '../icon';
|
|
4
4
|
export type StatusType = IStatus | 'confirm' | 'unknown';
|
|
5
5
|
export declare const statusMapToIconDefinition: {
|
|
6
|
-
info: import("@fortawesome/
|
|
7
|
-
success: import("@fortawesome/
|
|
8
|
-
warning: import("@fortawesome/
|
|
9
|
-
error: import("@fortawesome/
|
|
10
|
-
confirm: import("@fortawesome/
|
|
11
|
-
unknown: import("@fortawesome/
|
|
6
|
+
info: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
7
|
+
success: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
8
|
+
warning: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
9
|
+
error: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
10
|
+
confirm: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
11
|
+
unknown: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
12
12
|
};
|
|
13
|
-
export interface StatusIconProps extends Partial<
|
|
13
|
+
export interface StatusIconProps extends Partial<IconProps> {
|
|
14
14
|
status?: StatusType;
|
|
15
15
|
}
|
|
16
16
|
export declare const StatusIcon: import("react").MemoExoticComponent<({ status, ...props }: StatusIconProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
@@ -22,6 +22,6 @@ export interface StatusProps extends DivProps {
|
|
|
22
22
|
/** 是否播放动画,默认为false */
|
|
23
23
|
animation?: boolean;
|
|
24
24
|
/** {@link variant}为`icon`时生效,传递给`<StatusIcon/>`组件 */
|
|
25
|
-
iconProps?: Partial<
|
|
25
|
+
iconProps?: Partial<IconProps>;
|
|
26
26
|
}
|
|
27
27
|
export declare const Status: import("react").MemoExoticComponent<({ status, variant, label, animation, iconProps, ...props }: StatusProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
@@ -5,19 +5,15 @@ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const status_style_1 = require("./status.style");
|
|
7
7
|
const utils_1 = require("../../utils");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const faCircleExclamation_1 = require("@fortawesome/free-solid-svg-icons/faCircleExclamation");
|
|
11
|
-
const faCircleXmark_1 = require("@fortawesome/free-solid-svg-icons/faCircleXmark");
|
|
12
|
-
const faCircleQuestion_1 = require("@fortawesome/free-solid-svg-icons/faCircleQuestion");
|
|
13
|
-
const react_fontawesome_1 = require("@fortawesome/react-fontawesome");
|
|
8
|
+
const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
|
|
9
|
+
const icon_1 = require("../icon");
|
|
14
10
|
exports.statusMapToIconDefinition = {
|
|
15
|
-
info:
|
|
16
|
-
success:
|
|
17
|
-
warning:
|
|
18
|
-
error:
|
|
19
|
-
confirm:
|
|
20
|
-
unknown:
|
|
11
|
+
info: free_solid_svg_icons_1.faCircleInfo,
|
|
12
|
+
success: free_solid_svg_icons_1.faCircleCheck,
|
|
13
|
+
warning: free_solid_svg_icons_1.faCircleExclamation,
|
|
14
|
+
error: free_solid_svg_icons_1.faCircleXmark,
|
|
15
|
+
confirm: free_solid_svg_icons_1.faCircleQuestion,
|
|
16
|
+
unknown: free_solid_svg_icons_1.faCircleQuestion
|
|
21
17
|
};
|
|
22
18
|
exports.StatusIcon = (0, react_1.memo)(({ status = 'unknown', ...props }) => {
|
|
23
19
|
const statusColor = (0, utils_1.useStatusColor)(status);
|
|
@@ -30,7 +26,7 @@ exports.StatusIcon = (0, react_1.memo)(({ status = 'unknown', ...props }) => {
|
|
|
30
26
|
...props.style
|
|
31
27
|
}), [statusColor, props.style])
|
|
32
28
|
};
|
|
33
|
-
return (0, jsx_runtime_1.jsx)(
|
|
29
|
+
return (0, jsx_runtime_1.jsx)(icon_1.Icon, { ...iconProps });
|
|
34
30
|
});
|
|
35
31
|
const defaultLabel = {
|
|
36
32
|
unknown: '未知',
|
|
@@ -55,4 +55,8 @@ export declare function useLoading<A extends any[], R>(fn: (...args: A) => R | P
|
|
|
55
55
|
* @param effectContainer
|
|
56
56
|
* @param defaultContainer 默认为`document.body`
|
|
57
57
|
*/
|
|
58
|
-
export declare function useContainer<T extends HTMLElement | null>(container?: DefineElement<T>, effectContainer?: DefineElement<T>, defaultContainer?: T): RefObject<T>;
|
|
58
|
+
export declare function useContainer<T extends HTMLElement | null>(container?: DefineElement<T>, effectContainer?: DefineElement<T>, defaultContainer?: DefineElement<T>): RefObject<T | null>;
|
|
59
|
+
/**
|
|
60
|
+
* 使用外部类,该方法可避免`StrictMode`下,React渲染行为与外部类实例生命周期不同步的问题
|
|
61
|
+
*/
|
|
62
|
+
export declare function useExternalClass<T>(setup: () => T, cleanup?: (instance: T) => void): T;
|
package/dist/cjs/utils/hooks.js
CHANGED
|
@@ -9,6 +9,7 @@ exports.useUnmounted = useUnmounted;
|
|
|
9
9
|
exports.useControlled = useControlled;
|
|
10
10
|
exports.useLoading = useLoading;
|
|
11
11
|
exports.useContainer = useContainer;
|
|
12
|
+
exports.useExternalClass = useExternalClass;
|
|
12
13
|
const react_1 = require("react");
|
|
13
14
|
const utils_1 = require("./utils");
|
|
14
15
|
/**
|
|
@@ -130,18 +131,36 @@ function useLoading(fn, referredLoading = false) {
|
|
|
130
131
|
* @param effectContainer
|
|
131
132
|
* @param defaultContainer 默认为`document.body`
|
|
132
133
|
*/
|
|
133
|
-
function useContainer(container, effectContainer, defaultContainer
|
|
134
|
+
function useContainer(container, effectContainer, defaultContainer) {
|
|
134
135
|
const [containerEl, setContainerEl] = useDerivedState(prev => {
|
|
135
136
|
if (container) {
|
|
136
137
|
return typeof container === 'function' ? container() : container;
|
|
137
138
|
}
|
|
138
|
-
return prev ||
|
|
139
|
-
}, [container
|
|
139
|
+
return prev || null;
|
|
140
|
+
}, [container]);
|
|
140
141
|
(0, react_1.useEffect)(() => {
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
const _container = effectContainer || defaultContainer || document.body;
|
|
143
|
+
if (_container) {
|
|
144
|
+
const el = typeof _container === 'function' ? _container() : _container;
|
|
143
145
|
setContainerEl(el);
|
|
144
146
|
}
|
|
145
|
-
}, []);
|
|
147
|
+
}, [effectContainer, defaultContainer]);
|
|
146
148
|
return containerEl;
|
|
147
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* 使用外部类,该方法可避免`StrictMode`下,React渲染行为与外部类实例生命周期不同步的问题
|
|
152
|
+
*/
|
|
153
|
+
function useExternalClass(setup, cleanup) {
|
|
154
|
+
const mountTimes = (0, react_1.useRef)(0);
|
|
155
|
+
const prevInstance = (0, react_1.useRef)(void 0);
|
|
156
|
+
const [instance] = (0, react_1.useState)(() => {
|
|
157
|
+
if (!mountTimes.current++) {
|
|
158
|
+
prevInstance.current = setup();
|
|
159
|
+
}
|
|
160
|
+
return prevInstance.current;
|
|
161
|
+
});
|
|
162
|
+
(0, react_1.useEffect)(() => () => {
|
|
163
|
+
!--mountTimes.current && cleanup?.(instance);
|
|
164
|
+
}, []);
|
|
165
|
+
return instance;
|
|
166
|
+
}
|
|
@@ -4,7 +4,7 @@ import { clsx, useControlled } from '../../utils';
|
|
|
4
4
|
import { useTheme } from '../theme';
|
|
5
5
|
import { Collapse } from '../transitionBase';
|
|
6
6
|
import { Icon } from '../icon';
|
|
7
|
-
import { faCaretRight } from '@fortawesome/free-solid-svg-icons
|
|
7
|
+
import { faCaretRight } from '@fortawesome/free-solid-svg-icons';
|
|
8
8
|
export function Accordion({ size, title, prefix, suffix, expandIcon, defaultExpanded = false, expanded, onExpandedChange, readOnly, disabled, ...props }) {
|
|
9
9
|
const theme = useTheme();
|
|
10
10
|
size ??= theme.size;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext
|
|
3
|
-
import { clsx, defineCss } from '../../utils';
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
import { clsx, defineCss, useExternalClass } from '../../utils';
|
|
4
4
|
import { classes, style } from './app.style';
|
|
5
5
|
import { ThemeProvider } from '../theme';
|
|
6
6
|
import { AppDialog, AppDialogMethods } from './appDialog';
|
|
@@ -22,12 +22,12 @@ export const App = (({ theme, ...props }) => {
|
|
|
22
22
|
return (_jsx(GlobalEventDelegation, { children: _jsx(ThemeProvider, { theme: theme, children: _jsx(InnerApp, { ...props }) }) }));
|
|
23
23
|
});
|
|
24
24
|
export function InnerApp({ component: Component = 'div', theme, children, fill = true, ...props }) {
|
|
25
|
-
const appValue =
|
|
25
|
+
const appValue = useExternalClass(() => ({
|
|
26
26
|
dialog: App.dialog = new AppDialogMethods(),
|
|
27
27
|
message: App.message = new AppMessageMethods(),
|
|
28
28
|
notification: App.notification = new AppNotificationMethods(),
|
|
29
29
|
actionSheet: App.actionSheet = new AppActionSheetMethods()
|
|
30
|
-
})
|
|
30
|
+
}));
|
|
31
31
|
return (_jsxs(AppContext, { value: appValue, children: [Component
|
|
32
32
|
? _jsx(Component, { ...props, css: [
|
|
33
33
|
style,
|
|
@@ -37,7 +37,7 @@ export declare function ClickAway({ ref, container, eventType, onClickAway, disa
|
|
|
37
37
|
title: string;
|
|
38
38
|
translate: "yes" | "no";
|
|
39
39
|
radioGroup: string;
|
|
40
|
-
role: "article" | "button" | "dialog" | "figure" | "form" | "img" | "link" | "main" | "menu" | "menuitem" | "option" | "search" | "table" | "switch" | "status" | (string & {}) | "none" | "checkbox" | "listbox" | "radio" | "region" | "cell" | "grid" | "row" | "listitem" | "menubar" | "progressbar" | "separator" | "tab" | "tabpanel" | "toolbar" | "tooltip" | "treeitem" | "scrollbar" | "alert" | "alertdialog" | "application" | "banner" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "directory" | "document" | "feed" | "gridcell" | "group" | "heading" | "list" | "log" | "marquee" | "
|
|
40
|
+
role: "article" | "button" | "dialog" | "figure" | "form" | "img" | "link" | "main" | "menu" | "menuitem" | "option" | "search" | "table" | "switch" | "status" | (string & {}) | "none" | "checkbox" | "listbox" | "radio" | "region" | "cell" | "grid" | "row" | "math" | "listitem" | "menubar" | "progressbar" | "separator" | "tab" | "tabpanel" | "toolbar" | "tooltip" | "treeitem" | "scrollbar" | "alert" | "alertdialog" | "application" | "banner" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "directory" | "document" | "feed" | "gridcell" | "group" | "heading" | "list" | "log" | "marquee" | "menuitemcheckbox" | "menuitemradio" | "navigation" | "note" | "presentation" | "radiogroup" | "rowgroup" | "rowheader" | "searchbox" | "slider" | "spinbutton" | "tablist" | "term" | "textbox" | "timer" | "tree" | "treegrid";
|
|
41
41
|
about: string;
|
|
42
42
|
content: string;
|
|
43
43
|
datatype: string;
|
|
@@ -60,7 +60,7 @@ export declare function ClickAway({ ref, container, eventType, onClickAway, disa
|
|
|
60
60
|
results: number;
|
|
61
61
|
security: string;
|
|
62
62
|
unselectable: "off" | "on";
|
|
63
|
-
popover: "" | "auto" | "manual";
|
|
63
|
+
popover: "" | "auto" | "manual" | "hint";
|
|
64
64
|
popoverTargetAction: "hide" | "show" | "toggle";
|
|
65
65
|
popoverTarget: string;
|
|
66
66
|
inert: boolean;
|
|
@@ -70,7 +70,7 @@ export declare function ClickAway({ ref, container, eventType, onClickAway, disa
|
|
|
70
70
|
part: string;
|
|
71
71
|
"aria-activedescendant": string;
|
|
72
72
|
"aria-atomic": boolean | "false" | "true";
|
|
73
|
-
"aria-autocomplete": "
|
|
73
|
+
"aria-autocomplete": "none" | "both" | "inline" | "list";
|
|
74
74
|
"aria-braillelabel": string;
|
|
75
75
|
"aria-brailleroledescription": string;
|
|
76
76
|
"aria-busy": boolean | "false" | "true";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
|
|
2
2
|
import { ColorPropsValue } from '../../types';
|
|
3
|
-
|
|
3
|
+
import { IconDefinition } from '@fortawesome/free-brands-svg-icons';
|
|
4
|
+
export interface IconProps extends Omit<FontAwesomeIconProps, 'color' | 'icon'> {
|
|
4
5
|
color?: ColorPropsValue;
|
|
6
|
+
icon: FontAwesomeIconProps['icon'] | IconDefinition;
|
|
5
7
|
}
|
|
6
8
|
export declare function Icon({ color, ...props }: IconProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -24,4 +24,4 @@ export interface OverlayBaseProps extends DivProps {
|
|
|
24
24
|
removeFocusOnOpen?: boolean;
|
|
25
25
|
}
|
|
26
26
|
export declare const overlayBaseTransitionDuration = 300;
|
|
27
|
-
export declare function OverlayBase({ container, effectContainer, 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 | null;
|
|
@@ -33,7 +33,7 @@ export function OverlayBase({ container, effectContainer, forceRender, open, onM
|
|
|
33
33
|
onClosed?.();
|
|
34
34
|
forceRender === false && setShouldRender(false);
|
|
35
35
|
};
|
|
36
|
-
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, ...mergeComponentProps(maskProps, {
|
|
36
|
+
return shouldRender.current && containerEl.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, ...mergeComponentProps(maskProps, {
|
|
37
37
|
in: open,
|
|
38
38
|
className: classes.mask,
|
|
39
39
|
onClick,
|
|
@@ -19,7 +19,7 @@ const getAttemptOrder = (placement) => {
|
|
|
19
19
|
}
|
|
20
20
|
return order;
|
|
21
21
|
};
|
|
22
|
-
export function Popper({ ref, popperRef, anchorElement, container
|
|
22
|
+
export function Popper({ ref, popperRef, anchorElement, container, effectContainer, content, offset, trigger = 'hover', clickToClose, placement = 'top', variant = 'zoom', sizeAdaptable = variant === 'collapse', mouseEnterDelay = 150, 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, () => {
|
|
@@ -534,7 +534,7 @@ export function Popper({ ref, popperRef, anchorElement, container = document.bod
|
|
|
534
534
|
? cloneElement(children, {
|
|
535
535
|
ref: childRef
|
|
536
536
|
})
|
|
537
|
-
: children, renderedOnce.current && createPortal(_jsx(ClickAway, { disabled: !clickable && !enterable && !contextMenuable,
|
|
537
|
+
: children, renderedOnce.current && containerEl.current && createPortal(_jsx(ClickAway, { disabled: !clickable && !enterable && !contextMenuable,
|
|
538
538
|
// 右键菜单点击anchor需要关闭弹框
|
|
539
539
|
targets: () => contextMenuEvent.current ? void 0 : getAnchorElement(), onClickAway: onClickAway, children: _jsx("div", { ...props, ref: innerPopperRef, css: style, className: clsx(classes.root, props.className), style: {
|
|
540
540
|
...popperBounding,
|
|
@@ -30,7 +30,7 @@ export declare const SnackbarBase: React.MemoExoticComponent<({ methods, useTo,
|
|
|
30
30
|
max?: number;
|
|
31
31
|
container?: DefineElement<HTMLElement>;
|
|
32
32
|
effectContainer?: DefineElement<HTMLElement>;
|
|
33
|
-
}) => React.ReactPortal>;
|
|
33
|
+
}) => React.ReactPortal | null>;
|
|
34
34
|
interface SnackbarBaseItemProps extends Omit<SnackbarBaseProps, 'duration' | 'onAutoClose'> {
|
|
35
35
|
id: string;
|
|
36
36
|
type: keyof SnackbarBaseMethods;
|
|
@@ -82,7 +82,7 @@ export const SnackbarBase = memo(({ methods, useTo, max = useTo === 'message' ?
|
|
|
82
82
|
methods.error = defineMethod('error');
|
|
83
83
|
const css = style();
|
|
84
84
|
const containerEl = useContainer(container, effectContainer);
|
|
85
|
-
return createPortal(stacks.flatMap((stack, i) => stack
|
|
85
|
+
return containerEl.current && 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
87
|
: []), containerEl.current);
|
|
88
88
|
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { DivProps, Status as IStatus } from '../../types';
|
|
3
|
-
import {
|
|
3
|
+
import { IconProps } from '../icon';
|
|
4
4
|
export type StatusType = IStatus | 'confirm' | 'unknown';
|
|
5
5
|
export declare const statusMapToIconDefinition: {
|
|
6
|
-
info: import("@fortawesome/
|
|
7
|
-
success: import("@fortawesome/
|
|
8
|
-
warning: import("@fortawesome/
|
|
9
|
-
error: import("@fortawesome/
|
|
10
|
-
confirm: import("@fortawesome/
|
|
11
|
-
unknown: import("@fortawesome/
|
|
6
|
+
info: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
7
|
+
success: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
8
|
+
warning: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
9
|
+
error: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
10
|
+
confirm: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
11
|
+
unknown: import("@fortawesome/free-solid-svg-icons").IconDefinition;
|
|
12
12
|
};
|
|
13
|
-
export interface StatusIconProps extends Partial<
|
|
13
|
+
export interface StatusIconProps extends Partial<IconProps> {
|
|
14
14
|
status?: StatusType;
|
|
15
15
|
}
|
|
16
16
|
export declare const StatusIcon: import("react").MemoExoticComponent<({ status, ...props }: StatusIconProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
@@ -22,6 +22,6 @@ export interface StatusProps extends DivProps {
|
|
|
22
22
|
/** 是否播放动画,默认为false */
|
|
23
23
|
animation?: boolean;
|
|
24
24
|
/** {@link variant}为`icon`时生效,传递给`<StatusIcon/>`组件 */
|
|
25
|
-
iconProps?: Partial<
|
|
25
|
+
iconProps?: Partial<IconProps>;
|
|
26
26
|
}
|
|
27
27
|
export declare const Status: import("react").MemoExoticComponent<({ status, variant, label, animation, iconProps, ...props }: StatusProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
@@ -2,12 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
3
|
import { classes, style } from './status.style';
|
|
4
4
|
import { clsx, useStatusColor } from '../../utils';
|
|
5
|
-
import { faCircleInfo } from '@fortawesome/free-solid-svg-icons
|
|
6
|
-
import {
|
|
7
|
-
import { faCircleExclamation } from '@fortawesome/free-solid-svg-icons/faCircleExclamation';
|
|
8
|
-
import { faCircleXmark } from '@fortawesome/free-solid-svg-icons/faCircleXmark';
|
|
9
|
-
import { faCircleQuestion } from '@fortawesome/free-solid-svg-icons/faCircleQuestion';
|
|
10
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
5
|
+
import { faCircleInfo, faCircleCheck, faCircleExclamation, faCircleXmark, faCircleQuestion } from '@fortawesome/free-solid-svg-icons';
|
|
6
|
+
import { Icon } from '../icon';
|
|
11
7
|
export const statusMapToIconDefinition = {
|
|
12
8
|
info: faCircleInfo,
|
|
13
9
|
success: faCircleCheck,
|
|
@@ -27,7 +23,7 @@ export const StatusIcon = memo(({ status = 'unknown', ...props }) => {
|
|
|
27
23
|
...props.style
|
|
28
24
|
}), [statusColor, props.style])
|
|
29
25
|
};
|
|
30
|
-
return _jsx(
|
|
26
|
+
return _jsx(Icon, { ...iconProps });
|
|
31
27
|
});
|
|
32
28
|
const defaultLabel = {
|
|
33
29
|
unknown: '未知',
|
|
@@ -55,4 +55,8 @@ export declare function useLoading<A extends any[], R>(fn: (...args: A) => R | P
|
|
|
55
55
|
* @param effectContainer
|
|
56
56
|
* @param defaultContainer 默认为`document.body`
|
|
57
57
|
*/
|
|
58
|
-
export declare function useContainer<T extends HTMLElement | null>(container?: DefineElement<T>, effectContainer?: DefineElement<T>, defaultContainer?: T): RefObject<T>;
|
|
58
|
+
export declare function useContainer<T extends HTMLElement | null>(container?: DefineElement<T>, effectContainer?: DefineElement<T>, defaultContainer?: DefineElement<T>): RefObject<T | null>;
|
|
59
|
+
/**
|
|
60
|
+
* 使用外部类,该方法可避免`StrictMode`下,React渲染行为与外部类实例生命周期不同步的问题
|
|
61
|
+
*/
|
|
62
|
+
export declare function useExternalClass<T>(setup: () => T, cleanup?: (instance: T) => void): T;
|
package/dist/esm/utils/hooks.js
CHANGED
|
@@ -119,18 +119,36 @@ export function useLoading(fn, referredLoading = false) {
|
|
|
119
119
|
* @param effectContainer
|
|
120
120
|
* @param defaultContainer 默认为`document.body`
|
|
121
121
|
*/
|
|
122
|
-
export function useContainer(container, effectContainer, defaultContainer
|
|
122
|
+
export function useContainer(container, effectContainer, defaultContainer) {
|
|
123
123
|
const [containerEl, setContainerEl] = useDerivedState(prev => {
|
|
124
124
|
if (container) {
|
|
125
125
|
return typeof container === 'function' ? container() : container;
|
|
126
126
|
}
|
|
127
|
-
return prev ||
|
|
128
|
-
}, [container
|
|
127
|
+
return prev || null;
|
|
128
|
+
}, [container]);
|
|
129
129
|
useEffect(() => {
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
const _container = effectContainer || defaultContainer || document.body;
|
|
131
|
+
if (_container) {
|
|
132
|
+
const el = typeof _container === 'function' ? _container() : _container;
|
|
132
133
|
setContainerEl(el);
|
|
133
134
|
}
|
|
134
|
-
}, []);
|
|
135
|
+
}, [effectContainer, defaultContainer]);
|
|
135
136
|
return containerEl;
|
|
136
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* 使用外部类,该方法可避免`StrictMode`下,React渲染行为与外部类实例生命周期不同步的问题
|
|
140
|
+
*/
|
|
141
|
+
export function useExternalClass(setup, cleanup) {
|
|
142
|
+
const mountTimes = useRef(0);
|
|
143
|
+
const prevInstance = useRef(void 0);
|
|
144
|
+
const [instance] = useState(() => {
|
|
145
|
+
if (!mountTimes.current++) {
|
|
146
|
+
prevInstance.current = setup();
|
|
147
|
+
}
|
|
148
|
+
return prevInstance.current;
|
|
149
|
+
});
|
|
150
|
+
useEffect(() => () => {
|
|
151
|
+
!--mountTimes.current && cleanup?.(instance);
|
|
152
|
+
}, []);
|
|
153
|
+
return instance;
|
|
154
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canlooks/can-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.114",
|
|
4
4
|
"author": "C.CanLiang <canlooks@gmail.com>",
|
|
5
5
|
"description": "My ui framework",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,35 +51,35 @@
|
|
|
51
51
|
"@dnd-kit/core": "^6.3.1",
|
|
52
52
|
"@dnd-kit/sortable": "^10.0.0",
|
|
53
53
|
"@emotion/react": "^11.14.0",
|
|
54
|
-
"@fortawesome/free-brands-svg-icons": "^
|
|
55
|
-
"@fortawesome/free-regular-svg-icons": "^
|
|
56
|
-
"@fortawesome/free-solid-svg-icons": "^
|
|
57
|
-
"@fortawesome/react-fontawesome": "^
|
|
58
|
-
"color": "^5.0.
|
|
59
|
-
"dayjs": "^1.11.
|
|
54
|
+
"@fortawesome/free-brands-svg-icons": "^7.1.0",
|
|
55
|
+
"@fortawesome/free-regular-svg-icons": "^7.1.0",
|
|
56
|
+
"@fortawesome/free-solid-svg-icons": "^7.1.0",
|
|
57
|
+
"@fortawesome/react-fontawesome": "^3.1.1",
|
|
58
|
+
"color": "^5.0.3",
|
|
59
|
+
"dayjs": "^1.11.19",
|
|
60
60
|
"react-transition-group": "^4.4.5",
|
|
61
61
|
"tslib": "^2.8.1"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@ant-design/icons": "^6.
|
|
65
|
-
"@canlooks/react-router": "^1.0
|
|
66
|
-
"@canlooks/reactive": "^4.
|
|
67
|
-
"@emotion/styled": "^11.14.
|
|
64
|
+
"@ant-design/icons": "^6.1.0",
|
|
65
|
+
"@canlooks/react-router": "^1.1.0",
|
|
66
|
+
"@canlooks/reactive": "^4.7.10",
|
|
67
|
+
"@emotion/styled": "^11.14.1",
|
|
68
68
|
"@mdi/js": "^7.4.47",
|
|
69
69
|
"@mdi/react": "^1.6.1",
|
|
70
|
-
"@mui/icons-material": "^7.
|
|
71
|
-
"@types/node": "^
|
|
72
|
-
"@types/react": "^19.
|
|
73
|
-
"@types/react-dom": "^19.
|
|
70
|
+
"@mui/icons-material": "^7.3.6",
|
|
71
|
+
"@types/node": "^25.0.2",
|
|
72
|
+
"@types/react": "^19.2.7",
|
|
73
|
+
"@types/react-dom": "^19.2.3",
|
|
74
74
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
75
75
|
"@types/react-transition-group": "^4.4.12",
|
|
76
|
-
"mime": "^4.0
|
|
77
|
-
"react": "^19.
|
|
78
|
-
"react-dom": "^19.
|
|
76
|
+
"mime": "^4.1.0",
|
|
77
|
+
"react": "^19.2.3",
|
|
78
|
+
"react-dom": "^19.2.3",
|
|
79
79
|
"react-markdown": "^10.1.0",
|
|
80
|
-
"react-syntax-highlighter": "^
|
|
80
|
+
"react-syntax-highlighter": "^16.1.0",
|
|
81
81
|
"remark-gfm": "^4.0.1",
|
|
82
|
-
"typescript": "^5.
|
|
83
|
-
"vite": "^
|
|
82
|
+
"typescript": "^5.9.3",
|
|
83
|
+
"vite": "^7.3.0"
|
|
84
84
|
}
|
|
85
85
|
}
|