@huibo-ui/react-antd 1.0.10 → 1.0.12
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/LICENSE +21 -0
- package/lib/components/Affix.js +1 -1
- package/lib/components/Alert.js +1 -1
- package/lib/components/Avatar.js +4 -1
- package/lib/components/BackTop.js +1 -1
- package/lib/components/Badge.js +1 -1
- package/lib/components/Breadcrumb.js +4 -2
- package/lib/components/Button.js +3 -2
- package/lib/components/Card.d.ts +14 -1
- package/lib/components/Card.js +30 -3
- package/lib/components/Checkbox.d.ts +2 -0
- package/lib/components/Checkbox.js +14 -2
- package/lib/components/Collapse.d.ts +34 -4
- package/lib/components/Collapse.js +122 -4
- package/lib/components/Descriptions.js +3 -5
- package/lib/components/Divider.d.ts +8 -0
- package/lib/components/Divider.js +38 -3
- package/lib/components/Drawer.d.ts +7 -1
- package/lib/components/Drawer.js +167 -4
- package/lib/components/Dropdown.js +1 -1
- package/lib/components/FloatButton.js +1 -1
- package/lib/components/Form.d.ts +25 -14
- package/lib/components/Form.js +315 -92
- package/lib/components/Image.js +1 -1
- package/lib/components/Input.js +25 -4
- package/lib/components/InputNumber.d.ts +1 -1
- package/lib/components/InputNumber.js +15 -1
- package/lib/components/Layout.d.ts +1 -1
- package/lib/components/Layout.js +41 -16
- package/lib/components/Menu.js +55 -11
- package/lib/components/Modal.d.ts +4 -1
- package/lib/components/Modal.js +137 -20
- package/lib/components/PageHeader.js +1 -1
- package/lib/components/Pagination.js +1 -1
- package/lib/components/Popconfirm.js +1 -1
- package/lib/components/Popover.js +1 -1
- package/lib/components/Progress.js +1 -1
- package/lib/components/Radio.d.ts +5 -3
- package/lib/components/Radio.js +24 -13
- package/lib/components/Rate.js +1 -1
- package/lib/components/Result.js +1 -1
- package/lib/components/Segmented.d.ts +5 -3
- package/lib/components/Segmented.js +4 -1
- package/lib/components/Select.js +1 -1
- package/lib/components/Slider.d.ts +9 -2
- package/lib/components/Slider.js +8 -1
- package/lib/components/Space.d.ts +2 -1
- package/lib/components/Space.js +47 -4
- package/lib/components/Spin.js +1 -1
- package/lib/components/Statistic.d.ts +1 -0
- package/lib/components/Statistic.js +5 -1
- package/lib/components/Steps.js +4 -2
- package/lib/components/Switch.d.ts +6 -0
- package/lib/components/Switch.js +15 -1
- package/lib/components/Table.js +68 -12
- package/lib/components/Tabs.js +52 -27
- package/lib/components/Tag.d.ts +1 -0
- package/lib/components/Tag.js +16 -2
- package/lib/components/TimePicker.js +1 -1
- package/lib/components/Timeline.js +9 -1
- package/lib/components/Tooltip.js +1 -1
- package/lib/components/Tree.js +2 -4
- package/lib/components/TreeSelect.d.ts +2 -0
- package/lib/components/TreeSelect.js +19 -1
- package/lib/components/Typography.js +7 -3
- package/lib/components/Upload.js +1 -1
- package/lib/components/Watermark.js +21 -1
- package/lib/components/message.js +4 -3
- package/lib/components/notification.js +3 -1
- package/package.json +5 -6
package/lib/components/Menu.js
CHANGED
|
@@ -2,17 +2,23 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
const PRIMARY = 'var(--hb-color-primary, #ff6700)';
|
|
4
4
|
export function Menu(props) {
|
|
5
|
-
const { items, mode = 'vertical', selectedKeys, openKeys, theme = 'light', inlineCollapsed, onClick, onOpenChange, onSelect, style, className, children
|
|
5
|
+
const { items, mode = 'vertical', selectedKeys, openKeys, theme = 'light', inlineCollapsed, onClick, onOpenChange, onSelect, style, className, children } = props;
|
|
6
6
|
const horizontal = mode === 'horizontal';
|
|
7
7
|
const dark = theme === 'dark';
|
|
8
8
|
const [internalOpen, setInternalOpen] = React.useState(openKeys ?? []);
|
|
9
9
|
const openSet = openKeys !== undefined ? openKeys : internalOpen;
|
|
10
|
-
|
|
10
|
+
// 非受控选中:selectedKeys 未传时,点击菜单项应自动高亮选中(对齐 antd 默认行为)。
|
|
11
|
+
// 旧实现 selected 恒为 [](selectedKeys ?? []),点击后无选中视觉反馈。
|
|
12
|
+
const [internalSelected, setInternalSelected] = React.useState([]);
|
|
13
|
+
const selected = selectedKeys !== undefined ? selectedKeys : internalSelected;
|
|
11
14
|
const collapsed = !!inlineCollapsed;
|
|
12
15
|
const fireClick = (item, keyPath) => {
|
|
13
16
|
if (item.disabled)
|
|
14
17
|
return;
|
|
15
18
|
const info = { key: item.key, keyPath: [item.key, ...keyPath], item };
|
|
19
|
+
// 非受控模式:内部更新选中态,触发高亮重渲染
|
|
20
|
+
if (selectedKeys === undefined)
|
|
21
|
+
setInternalSelected([item.key]);
|
|
16
22
|
onClick?.(info);
|
|
17
23
|
onSelect?.({ key: item.key, keyPath: info.keyPath });
|
|
18
24
|
};
|
|
@@ -22,24 +28,26 @@ export function Menu(props) {
|
|
|
22
28
|
setInternalOpen(next);
|
|
23
29
|
onOpenChange?.(next);
|
|
24
30
|
};
|
|
25
|
-
const Icon = ({ icon }) => icon ?
|
|
31
|
+
const Icon = ({ icon }) => icon ? _jsx("span", { style: { display: 'inline-flex', alignItems: 'center', marginRight: 8, width: 16, height: 16 }, children: icon }) : null;
|
|
26
32
|
const textColor = dark ? 'rgba(255,255,255,0.85)' : 'rgba(0,0,0,0.88)';
|
|
27
33
|
const disabledColor = dark ? 'rgba(255,255,255,0.25)' : 'rgba(0,0,0,0.25)';
|
|
28
34
|
const renderItem = (item, keyPath) => {
|
|
29
35
|
const hasChildren = !!(item.children && item.children.length > 0);
|
|
30
36
|
const isSelected = selected.includes(item.key);
|
|
31
37
|
const isOpen = openSet.includes(item.key);
|
|
32
|
-
const labelColor = item.disabled ? disabledColor : isSelected ? PRIMARY : textColor;
|
|
33
38
|
if (hasChildren && !collapsed) {
|
|
34
|
-
return (_jsxs("li", { role: "menuitem", style: { listStyle: 'none' }, children: [_jsxs("div", { onClick: () => !item.disabled && toggleSub(item.key), style: {
|
|
39
|
+
return (_jsxs("li", { role: "menuitem", style: { listStyle: 'none' }, children: [_jsxs("div", { onClick: () => !item.disabled && toggleSub(item.key), className: `hb-menu__item-li${isSelected ? ' hb-menu__item-li--selected' : ''}`, style: {
|
|
35
40
|
display: 'flex',
|
|
36
41
|
alignItems: 'center',
|
|
37
42
|
height: 40,
|
|
38
43
|
padding: collapsed ? 0 : '0 16px',
|
|
39
44
|
cursor: item.disabled ? 'not-allowed' : 'pointer',
|
|
40
|
-
color:
|
|
45
|
+
color: item.disabled ? disabledColor : undefined,
|
|
41
46
|
whiteSpace: 'nowrap',
|
|
42
|
-
|
|
47
|
+
boxSizing: 'border-box',
|
|
48
|
+
borderRadius: 6,
|
|
49
|
+
margin: '2px 8px',
|
|
50
|
+
}, children: [_jsx(Icon, { icon: item.icon }), _jsx("span", { style: { flex: 1, overflow: 'hidden', textOverflow: 'ellipsis' }, children: item.label }), _jsx("span", { style: { display: 'inline-block', transition: 'transform .2s', transform: isOpen ? 'rotate(90deg)' : 'none', fontSize: 10, marginLeft: 8 }, children: "\u25B6" })] }), _jsx("div", { className: `hb-menu__submenu${isOpen ? ' hb-menu__submenu--open' : ''}`, children: _jsx("div", { children: _jsx("ul", { role: "menu", style: { listStyle: 'none', margin: 0, padding: 0 }, children: item.children.map(c => renderItem(c, [item.key, ...keyPath])) }) }) })] }, item.key));
|
|
43
51
|
}
|
|
44
52
|
// 叶子项
|
|
45
53
|
const baseStyle = {
|
|
@@ -48,16 +56,50 @@ export function Menu(props) {
|
|
|
48
56
|
height: horizontal ? 56 : 40,
|
|
49
57
|
padding: horizontal ? '0 20px' : collapsed ? 0 : '0 16px',
|
|
50
58
|
cursor: item.disabled ? 'not-allowed' : 'pointer',
|
|
51
|
-
color
|
|
52
|
-
|
|
59
|
+
// color/background 不在 inline 设:交给 .hb-menu__item-li(--selected) class 控制,
|
|
60
|
+
// 否则 inline 优先级高于 class,选中态的文字色/背景色会被覆盖。
|
|
61
|
+
color: item.disabled ? disabledColor : undefined,
|
|
53
62
|
borderBottom: horizontal && isSelected ? `2px solid ${PRIMARY}` : 'none',
|
|
54
63
|
whiteSpace: 'nowrap',
|
|
55
64
|
listStyle: 'none',
|
|
65
|
+
boxSizing: 'border-box',
|
|
66
|
+
borderRadius: horizontal ? 0 : 6,
|
|
67
|
+
margin: horizontal ? 0 : '2px 8px',
|
|
56
68
|
};
|
|
57
|
-
return (_jsxs("li", { role: "menuitem", onClick: () => fireClick(item, keyPath), style: baseStyle, children: [_jsx(Icon, { icon: item.icon }), _jsx("span", { style: { overflow: 'hidden', textOverflow: 'ellipsis' }, children: item.label })] }, item.key));
|
|
69
|
+
return (_jsxs("li", { role: "menuitem", onClick: () => fireClick(item, keyPath), className: `hb-menu__item-li${isSelected ? ' hb-menu__item-li--selected' : ''}`, style: baseStyle, children: [_jsx(Icon, { icon: item.icon }), _jsx("span", { style: { overflow: 'hidden', textOverflow: 'ellipsis' }, children: item.label })] }, item.key));
|
|
58
70
|
};
|
|
59
71
|
const list = items && items.length > 0 ? items : [];
|
|
60
|
-
|
|
72
|
+
// 唯一类名前缀,避免多实例样式冲突(hover/选中指示条需 CSS 伪类,inline style 做不到)。
|
|
73
|
+
const scope = React.useMemo(() => `hb-menu-${Math.random().toString(36).slice(2, 9)}`, []);
|
|
74
|
+
const selectedBg = dark ? 'rgba(255,255,255,0.08)' : 'rgba(22,119,255,0.06)';
|
|
75
|
+
const hoverBg = dark ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.04)';
|
|
76
|
+
// hover/选中指示条样式:CSS 伪类(:hover / ::after)无法用 inline style 表达,
|
|
77
|
+
// 注入到 document.head(注意 <ul> 内放 <style> 会被浏览器按内容模型忽略/移位,故必须放 head)。
|
|
78
|
+
// 带scope类名隔离,组件卸载时移除。
|
|
79
|
+
React.useEffect(() => {
|
|
80
|
+
if (typeof document === 'undefined')
|
|
81
|
+
return;
|
|
82
|
+
const styleEl = document.createElement('style');
|
|
83
|
+
styleEl.dataset.hbMenuScope = scope;
|
|
84
|
+
styleEl.textContent = `
|
|
85
|
+
.${scope} .hb-menu__item-li { position: relative; transition: background 0.2s, color 0.2s; color: ${textColor}; }
|
|
86
|
+
.${scope} .hb-menu__item-li:hover { background: ${hoverBg}; }
|
|
87
|
+
.${scope} .hb-menu__item-li--selected { background: ${selectedBg}; color: ${PRIMARY}; }
|
|
88
|
+
.${scope} .hb-menu__item-li--selected:hover { background: ${selectedBg}; }
|
|
89
|
+
.${scope}.hb-menu--inline .hb-menu__item-li--selected::after,
|
|
90
|
+
.${scope}.hb-menu--vertical .hb-menu__item-li--selected::after {
|
|
91
|
+
content: ''; position: absolute; right: 0; top: 0; bottom: 0; width: 3px; background: ${PRIMARY};
|
|
92
|
+
}
|
|
93
|
+
.${scope} .hb-menu__submenu { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s cubic-bezier(0.645,0.045,0.355,1); overflow: hidden; }
|
|
94
|
+
.${scope} .hb-menu__submenu--open { grid-template-rows: 1fr; }
|
|
95
|
+
.${scope} .hb-menu__submenu > div { min-height: 0; }
|
|
96
|
+
`;
|
|
97
|
+
document.head.appendChild(styleEl);
|
|
98
|
+
return () => {
|
|
99
|
+
styleEl.remove();
|
|
100
|
+
};
|
|
101
|
+
}, [scope, dark, hoverBg, selectedBg]);
|
|
102
|
+
return (_jsxs("ul", { role: "menu", className: `${scope} hb-menu--${mode} ${className || ''}`, style: {
|
|
61
103
|
listStyle: 'none',
|
|
62
104
|
margin: 0,
|
|
63
105
|
padding: inlineCollapsed || collapsed ? 0 : horizontal ? 0 : '8px 0',
|
|
@@ -67,6 +109,8 @@ export function Menu(props) {
|
|
|
67
109
|
background: dark ? '#001529' : '#fff',
|
|
68
110
|
color: textColor,
|
|
69
111
|
borderBottom: horizontal ? `1px solid ${dark ? '#1f1f1f' : '#f0f0f0'}` : 'none',
|
|
112
|
+
// 对齐 antd:inline 菜单无右边框(旧实现可能带边框线,这里显式 none)
|
|
113
|
+
borderRight: 'none',
|
|
70
114
|
minWidth: horizontal ? 0 : collapsed ? 0 : 200,
|
|
71
115
|
height: horizontal ? 56 : '100%',
|
|
72
116
|
boxSizing: 'border-box',
|
|
@@ -15,8 +15,11 @@ export interface ModalProps {
|
|
|
15
15
|
footer?: React.ReactNode | null;
|
|
16
16
|
children?: React.ReactNode;
|
|
17
17
|
style?: React.CSSProperties;
|
|
18
|
+
className?: string;
|
|
19
|
+
centered?: boolean;
|
|
20
|
+
closable?: boolean;
|
|
18
21
|
}
|
|
19
|
-
export declare function Modal(props: ModalProps): React.JSX.Element;
|
|
22
|
+
export declare function Modal(props: ModalProps): React.JSX.Element | null;
|
|
20
23
|
export declare namespace Modal {
|
|
21
24
|
var confirm: any;
|
|
22
25
|
var info: any;
|
package/lib/components/Modal.js
CHANGED
|
@@ -1,16 +1,141 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* antd Modal 兼容层(纯 div 实现)。
|
|
5
|
+
*
|
|
6
|
+
* 不再走 <HbDialog>(Shadow DOM slot):弹窗 body/footer 内容进 slot 后,<Form>/<Descriptions>
|
|
7
|
+
* 等嵌套布局会受 ::slotted 干扰,且 hb-dialog 的 footer 受限(不支持任意 ReactNode)。
|
|
8
|
+
* 纯 div 自渲染 mask + 居中容器 + header/body/footer,children 作为真实 DOM,嵌套表单布局稳定。
|
|
9
|
+
* 动画复刻 hb-dialog 的 fade+zoom(@keyframes 内联,不依赖 hb-*)。
|
|
10
|
+
*
|
|
11
|
+
* 命令式 API(confirm/info/warning/success/error)与 useModal 保留不变。
|
|
12
|
+
*/
|
|
13
|
+
// @keyframes 只需注入一次;用模块级标志避免重复插入。
|
|
14
|
+
let motionInjected = false;
|
|
15
|
+
function injectMotion() {
|
|
16
|
+
if (motionInjected || typeof document === 'undefined')
|
|
17
|
+
return;
|
|
18
|
+
motionInjected = true;
|
|
19
|
+
const style = document.createElement('style');
|
|
20
|
+
style.setAttribute('data-hb-modal-motion', '');
|
|
21
|
+
style.textContent = `
|
|
22
|
+
@keyframes hb-modal-overlay-in { from { opacity: 0; } to { opacity: 1; } }
|
|
23
|
+
@keyframes hb-modal-overlay-out { from { opacity: 1; } to { opacity: 0; } }
|
|
24
|
+
@keyframes hb-modal-in {
|
|
25
|
+
from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
|
|
26
|
+
to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
|
27
|
+
}
|
|
28
|
+
@keyframes hb-modal-out {
|
|
29
|
+
from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
|
30
|
+
to { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
document.head.appendChild(style);
|
|
34
|
+
}
|
|
35
|
+
const CloseIcon = () => (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 1024 1024", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { d: "M563.8 512l262.5-312.9c14.4-17.2.5-43.1-21.3-43.1H704.5c-7.9 0-15.4 3.5-20.5 9.5L512 417.8 339.9 165.5c-5.1-6-12.6-9.5-20.5-9.5H198.7c-21.8 0-35.7 25.9-21.3 43.1L439.9 512 177.4 824.9c-14.4 17.2-.5 43.1 21.3 43.1h120.5c7.9 0 15.4-3.5 20.5-9.5L512 606.2l172.1 252.3c5.1 6 12.6 9.5 20.5 9.5h120.5c21.8 0 35.7-25.9 21.3-43.1L563.8 512z" }) }));
|
|
4
36
|
export function Modal(props) {
|
|
5
|
-
const { open, title, width, onCancel, onOk, confirmLoading, okText, cancelText, maskClosable = true, keyboard = true, destroyOnClose, footer, children } = props;
|
|
6
|
-
|
|
7
|
-
|
|
37
|
+
const { open, title, width, onCancel, onOk, confirmLoading, okText, cancelText, maskClosable = true, keyboard = true, destroyOnClose, footer, children, style, className, centered = true, closable = true, } = props;
|
|
38
|
+
injectMotion();
|
|
39
|
+
// 离场动画:open 由 true→false 时保留 DOM 播 0.3s 出场再卸载。
|
|
40
|
+
const [leaving, setLeaving] = React.useState(false);
|
|
41
|
+
const prevOpen = React.useRef(!!open);
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
if (open && !prevOpen.current) {
|
|
44
|
+
setLeaving(false);
|
|
45
|
+
}
|
|
46
|
+
else if (!open && prevOpen.current) {
|
|
47
|
+
setLeaving(true);
|
|
48
|
+
const t = setTimeout(() => setLeaving(false), 300);
|
|
49
|
+
return () => clearTimeout(t);
|
|
50
|
+
}
|
|
51
|
+
prevOpen.current = !!open;
|
|
52
|
+
}, [open]);
|
|
53
|
+
// Esc 关闭
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
if (!open || !keyboard)
|
|
56
|
+
return;
|
|
57
|
+
const onKey = (e) => {
|
|
58
|
+
if (e.key === 'Escape')
|
|
59
|
+
onCancel?.({});
|
|
60
|
+
};
|
|
61
|
+
window.addEventListener('keydown', onKey);
|
|
62
|
+
return () => window.removeEventListener('keydown', onKey);
|
|
63
|
+
}, [open, keyboard, onCancel]);
|
|
64
|
+
// body 滚动锁定:弹层显示时锁住 body 滚动,避免关闭时页面因滚动条显隐而 reflow 闪烁。
|
|
65
|
+
// 用引用计数支持多个弹层叠加;compensate scrollbar 宽度避免横向跳动。
|
|
66
|
+
React.useEffect(() => {
|
|
67
|
+
if (!open)
|
|
68
|
+
return;
|
|
69
|
+
const body = document.body;
|
|
70
|
+
const prevOverflow = body.style.overflow;
|
|
71
|
+
const prevPaddingRight = body.style.paddingRight;
|
|
72
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
73
|
+
if (scrollbarWidth > 0)
|
|
74
|
+
body.style.paddingRight = `${scrollbarWidth}px`;
|
|
75
|
+
body.style.overflow = 'hidden';
|
|
76
|
+
return () => {
|
|
77
|
+
body.style.overflow = prevOverflow;
|
|
78
|
+
body.style.paddingRight = prevPaddingRight;
|
|
79
|
+
};
|
|
80
|
+
}, [open]);
|
|
81
|
+
// 显示条件 = open || leaving;都为 false 时完全卸载,
|
|
82
|
+
// 否则 open=false 后 modal/遮罩仍 fixed 显示,挡住下层。
|
|
83
|
+
if (!open && !leaving)
|
|
84
|
+
return null;
|
|
85
|
+
const defaultFooter = (_jsxs("div", { style: { textAlign: 'right', display: 'flex', justifyContent: 'flex-end', gap: 8 }, children: [_jsx("button", { type: "button", onClick: e => onCancel?.(e), style: { padding: '4px 15px', height: 32, borderRadius: 6, border: '1px solid #d9d9d9', background: '#fff', cursor: 'pointer', fontSize: 14 }, children: cancelText || '取消' }), _jsx("button", { type: "button", disabled: confirmLoading, onClick: e => onOk?.(e), style: { padding: '4px 15px', height: 32, borderRadius: 6, border: 'none', background: 'var(--hb-color-primary, #ff6700)', color: '#fff', cursor: 'pointer', fontSize: 14 }, children: confirmLoading ? '加载中...' : okText || '确定' })] }));
|
|
8
86
|
const resolvedFooter = footer === undefined ? defaultFooter : footer;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
87
|
+
const resolvedWidth = width == null ? 520 : typeof width === 'number' ? `${width}px` : String(width);
|
|
88
|
+
return (_jsxs("div", { style: { position: 'fixed', inset: 0, zIndex: 1000, pointerEvents: 'none' }, children: [_jsx("div", { onClick: () => maskClosable && onCancel?.({}), style: {
|
|
89
|
+
position: 'fixed',
|
|
90
|
+
inset: 0,
|
|
91
|
+
background: 'var(--hb-color-bg-mask, rgba(0,0,0,0.45))',
|
|
92
|
+
pointerEvents: 'auto',
|
|
93
|
+
animation: `${leaving ? 'hb-modal-overlay-out' : 'hb-modal-overlay-in'} 0.3s ease both`,
|
|
94
|
+
} }), _jsxs("div", { style: {
|
|
95
|
+
position: 'fixed',
|
|
96
|
+
top: centered ? '50%' : 100,
|
|
97
|
+
left: '50%',
|
|
98
|
+
width: resolvedWidth,
|
|
99
|
+
maxWidth: 'calc(100vw - 32px)',
|
|
100
|
+
background: 'var(--hb-color-bg-elevated, #fff)',
|
|
101
|
+
borderRadius: 8,
|
|
102
|
+
boxShadow: '0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05)',
|
|
103
|
+
pointerEvents: 'auto',
|
|
104
|
+
display: 'flex',
|
|
105
|
+
flexDirection: 'column',
|
|
106
|
+
maxHeight: 'calc(100vh - 32px)',
|
|
107
|
+
overflow: 'hidden',
|
|
108
|
+
zIndex: 1050,
|
|
109
|
+
transform: centered ? 'translate(-50%, -50%)' : 'translateX(-50%)',
|
|
110
|
+
animation: `${leaving ? 'hb-modal-out' : 'hb-modal-in'} 0.3s cubic-bezier(0.16, 1, 0.3, 1) both`,
|
|
111
|
+
...style,
|
|
112
|
+
}, className: className, children: [(title !== undefined || closable) && (_jsxs("div", { style: {
|
|
113
|
+
display: 'flex',
|
|
114
|
+
alignItems: 'center',
|
|
115
|
+
justifyContent: 'space-between',
|
|
116
|
+
padding: '16px 24px',
|
|
117
|
+
borderBottom: '1px solid var(--hb-color-border-secondary, #f0f0f0)',
|
|
118
|
+
}, children: [_jsx("div", { style: { fontSize: 16, fontWeight: 600, color: 'var(--hb-color-text, rgba(0,0,0,0.88))' }, children: title }), closable && (_jsx("button", { type: "button", onClick: e => onCancel?.(e), "aria-label": "close", style: {
|
|
119
|
+
display: 'inline-flex',
|
|
120
|
+
alignItems: 'center',
|
|
121
|
+
justifyContent: 'center',
|
|
122
|
+
width: 22,
|
|
123
|
+
height: 22,
|
|
124
|
+
border: 'none',
|
|
125
|
+
background: 'none',
|
|
126
|
+
color: 'var(--hb-color-text-secondary, rgba(0,0,0,0.45))',
|
|
127
|
+
cursor: 'pointer',
|
|
128
|
+
borderRadius: '50%',
|
|
129
|
+
padding: 0,
|
|
130
|
+
transition: 'all 0.2s',
|
|
131
|
+
}, onMouseEnter: e => (e.currentTarget.style.background = 'var(--hb-color-fill-tertiary, #fafafa)'), onMouseLeave: e => (e.currentTarget.style.background = 'none'), children: _jsx(CloseIcon, {}) }))] })), _jsx("div", { style: { flex: 1, padding: 24, overflowY: 'auto', color: 'var(--hb-color-text, rgba(0,0,0,0.88))', fontSize: 14 }, children: children }), resolvedFooter !== null && resolvedFooter !== undefined && (_jsx("div", { style: {
|
|
132
|
+
display: 'flex',
|
|
133
|
+
alignItems: 'center',
|
|
134
|
+
justifyContent: 'flex-end',
|
|
135
|
+
gap: 8,
|
|
136
|
+
padding: '8px 24px',
|
|
137
|
+
borderTop: '1px solid var(--hb-color-border-secondary, #f0f0f0)',
|
|
138
|
+
}, children: resolvedFooter }))] })] }));
|
|
14
139
|
}
|
|
15
140
|
function imperative(opts) {
|
|
16
141
|
const div = document.createElement('div');
|
|
@@ -21,7 +146,6 @@ function imperative(opts) {
|
|
|
21
146
|
return;
|
|
22
147
|
destroyed = true;
|
|
23
148
|
if (!root) {
|
|
24
|
-
// createRoot 尚未就绪(import 未完成),直接移除容器
|
|
25
149
|
div.remove();
|
|
26
150
|
return;
|
|
27
151
|
}
|
|
@@ -29,13 +153,12 @@ function imperative(opts) {
|
|
|
29
153
|
setTimeout(() => {
|
|
30
154
|
root.unmount();
|
|
31
155
|
div.remove();
|
|
32
|
-
},
|
|
156
|
+
}, 300);
|
|
33
157
|
};
|
|
34
158
|
let root;
|
|
35
|
-
// 动态拿到 createRoot
|
|
36
159
|
import('react-dom/client').then(({ createRoot }) => {
|
|
37
160
|
root = createRoot(div);
|
|
38
|
-
const showCancel = opts.okCancel !== false;
|
|
161
|
+
const showCancel = opts.okCancel !== false;
|
|
39
162
|
root.render(React.createElement(Modal, {
|
|
40
163
|
open: true,
|
|
41
164
|
title: opts.title,
|
|
@@ -53,7 +176,7 @@ function imperative(opts) {
|
|
|
53
176
|
destroy();
|
|
54
177
|
}
|
|
55
178
|
},
|
|
56
|
-
footer: null,
|
|
179
|
+
footer: null,
|
|
57
180
|
}, opts.content));
|
|
58
181
|
});
|
|
59
182
|
return { destroy };
|
|
@@ -63,11 +186,6 @@ Modal.info = ((p) => imperative({ ...p, type: 'info', okCancel: false }));
|
|
|
63
186
|
Modal.warning = ((p) => imperative({ ...p, type: 'warning', okCancel: false }));
|
|
64
187
|
Modal.success = ((p) => imperative({ ...p, type: 'success', okCancel: false }));
|
|
65
188
|
Modal.error = ((p) => imperative({ ...p, type: 'error', okCancel: false }));
|
|
66
|
-
/**
|
|
67
|
-
* useModal —— 返回 [modal, contextHolder]。
|
|
68
|
-
* contextHolder 需渲染在组件树里(占位用,当前实现命令式调用走 body 挂载,holder 可不渲染内容)。
|
|
69
|
-
* modal 实例提供 confirm/info/warning/success/error,与静态方法同义。
|
|
70
|
-
*/
|
|
71
189
|
Modal.useModal = function useModal() {
|
|
72
190
|
const api = React.useMemo(() => ({
|
|
73
191
|
confirm: (p) => imperative({ ...p, type: 'confirm', okCancel: true }),
|
|
@@ -76,7 +194,6 @@ Modal.useModal = function useModal() {
|
|
|
76
194
|
success: (p) => imperative({ ...p, type: 'success', okCancel: false }),
|
|
77
195
|
error: (p) => imperative({ ...p, type: 'error', okCancel: false }),
|
|
78
196
|
}), []);
|
|
79
|
-
// holder:命令式调用自己挂 body,这里返回空占位以满足 antd 的解构用法
|
|
80
197
|
const holder = React.createElement(React.Fragment, null);
|
|
81
198
|
return [api, holder];
|
|
82
199
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbPageHeader } from '@huibo-ui/react';
|
|
3
3
|
export function PageHeader(props) {
|
|
4
|
-
return _jsx(HbPageHeader, { title: typeof props.title === 'string' ? props.title : '', subtitle: typeof props.subTitle === 'string' ? props.subTitle : '', extra: props.extra, showBack: !!props.onBack });
|
|
4
|
+
return (_jsx(HbPageHeader, { title: typeof props.title === 'string' ? props.title : '', subtitle: typeof props.subTitle === 'string' ? props.subTitle : '', extra: props.extra, showBack: !!props.onBack }));
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbPagination } from '@huibo-ui/react';
|
|
3
3
|
export function Pagination(props) {
|
|
4
|
-
return _jsx(HbPagination, { "current-page": props.current ?? 1, "page-size": props.pageSize ?? 10, total: props.total ?? 0, "show-page-size": props.showSizeChanger, "page-sizes": props.pageSizeOptions?.map(Number), onHbCurrentChange: (e) => props.onChange?.(e.detail, props.pageSize ?? 10), style: props.style });
|
|
4
|
+
return (_jsx(HbPagination, { "current-page": props.current ?? 1, "page-size": props.pageSize ?? 10, total: props.total ?? 0, "show-page-size": props.showSizeChanger, "page-sizes": props.pageSizeOptions?.map(Number), onHbCurrentChange: (e) => props.onChange?.(e.detail, props.pageSize ?? 10), style: props.style }));
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbPopconfirm } from '@huibo-ui/react';
|
|
3
3
|
export function Popconfirm(props) {
|
|
4
|
-
return _jsx(HbPopconfirm, { title: typeof props.title === 'string' ? props.title : '', confirmText: props.okText, cancelText: props.cancelText, position: (props.placement || 'top'), onHbConfirm: () => props.onConfirm?.(), onHbCancel: () => props.onCancel?.(), children: props.children });
|
|
4
|
+
return (_jsx(HbPopconfirm, { title: typeof props.title === 'string' ? props.title : '', confirmText: props.okText, cancelText: props.cancelText, position: (props.placement || 'top'), onHbConfirm: () => props.onConfirm?.(), onHbCancel: () => props.onCancel?.(), children: props.children }));
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbPopover } from '@huibo-ui/react';
|
|
3
3
|
export function Popover(props) {
|
|
4
|
-
return _jsx(HbPopover, { content: props.content, title: typeof props.title === 'string' ? props.title : '', position: (props.placement || 'top'), trigger: (props.trigger || 'hover'), children: props.children });
|
|
4
|
+
return (_jsx(HbPopover, { content: props.content, title: typeof props.title === 'string' ? props.title : '', position: (props.placement || 'top'), trigger: (props.trigger || 'hover'), children: props.children }));
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbProgress } from '@huibo-ui/react';
|
|
3
3
|
export function Progress(props) {
|
|
4
|
-
return _jsx(HbProgress, { percentage: props.percent ?? 0, type: props.type, status: props.status, showText: props.showInfo ?? true, strokeColor: props.strokeColor, strokeWidth: props.strokeWidth, style: props.style });
|
|
4
|
+
return (_jsx(HbProgress, { percentage: props.percent ?? 0, type: props.type, status: props.status, showText: props.showInfo ?? true, strokeColor: props.strokeColor, strokeWidth: props.strokeWidth, style: props.style }));
|
|
5
5
|
}
|
|
@@ -2,9 +2,10 @@ import React from 'react';
|
|
|
2
2
|
export declare function Radio(props: {
|
|
3
3
|
value?: any;
|
|
4
4
|
checked?: boolean;
|
|
5
|
-
onChange?: (e: any) => void;
|
|
6
5
|
disabled?: boolean;
|
|
7
6
|
children?: React.ReactNode;
|
|
7
|
+
onChange?: (e: any) => void;
|
|
8
|
+
style?: React.CSSProperties;
|
|
8
9
|
}): React.JSX.Element;
|
|
9
10
|
export declare namespace Radio {
|
|
10
11
|
var Group: any;
|
|
@@ -12,12 +13,13 @@ export declare namespace Radio {
|
|
|
12
13
|
}
|
|
13
14
|
export declare function RadioGroup(props: {
|
|
14
15
|
value?: any;
|
|
16
|
+
defaultValue?: any;
|
|
15
17
|
onChange?: (value: any) => void;
|
|
16
|
-
options?: {
|
|
18
|
+
options?: Array<{
|
|
17
19
|
value: any;
|
|
18
20
|
label: React.ReactNode;
|
|
19
21
|
disabled?: boolean;
|
|
20
|
-
}
|
|
22
|
+
}>;
|
|
21
23
|
disabled?: boolean;
|
|
22
24
|
children?: React.ReactNode;
|
|
23
25
|
style?: React.CSSProperties;
|
package/lib/components/Radio.js
CHANGED
|
@@ -1,23 +1,34 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { HbRadio } from '@huibo-ui/react';
|
|
4
|
+
const GroupContext = React.createContext(null);
|
|
3
5
|
export function Radio(props) {
|
|
4
|
-
|
|
6
|
+
const ctx = React.useContext(GroupContext);
|
|
7
|
+
const isChecked = ctx ? ctx.value === props.value : props.checked;
|
|
8
|
+
const disabled = ctx?.disabled || props.disabled;
|
|
9
|
+
return (_jsx(HbRadio, { value: props.value, checked: isChecked ?? false, disabled: disabled, label: props.children, onHbChange: () => {
|
|
10
|
+
if (ctx)
|
|
11
|
+
ctx.onChange(props.value);
|
|
12
|
+
props.onChange?.({ target: { value: props.value, checked: true } });
|
|
13
|
+
}, style: props.style, children: props.children }));
|
|
5
14
|
}
|
|
6
|
-
// RadioGroup:huibo-ui 无独立 hb-radio-group 组件,用 div + 多个 hb-radio 实现
|
|
7
15
|
export function RadioGroup(props) {
|
|
8
|
-
const { value, onChange, options, disabled } = props;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const { value: ctrlValue, defaultValue, onChange, options, disabled, children, style } = props;
|
|
17
|
+
const isControlled = ctrlValue !== undefined;
|
|
18
|
+
const [inner, setInner] = React.useState(defaultValue);
|
|
19
|
+
const selected = isControlled ? ctrlValue : inner;
|
|
20
|
+
const handleChange = React.useCallback((val) => {
|
|
21
|
+
if (!isControlled)
|
|
22
|
+
setInner(val);
|
|
23
|
+
onChange?.(val);
|
|
24
|
+
}, [isControlled, onChange]);
|
|
25
|
+
const ctx = React.useMemo(() => ({ value: selected, disabled, onChange: handleChange }), [selected, disabled, handleChange]);
|
|
26
|
+
return (_jsx(GroupContext.Provider, { value: ctx, children: _jsx("div", { style: style, children: options
|
|
27
|
+
? options.map((opt, i) => (_jsx(HbRadio, { value: opt.value, checked: selected === opt.value, disabled: disabled || opt.disabled, label: opt.label, onHbChange: () => handleChange(opt.value) }, i)))
|
|
28
|
+
: children }) }));
|
|
14
29
|
}
|
|
15
|
-
// 挂上 antd 静态子组件(Radio.Group / Radio.Button)
|
|
16
30
|
Radio.Group = RadioGroup;
|
|
17
|
-
/**
|
|
18
|
-
* Radio.Button —— 样式变体,huibo hb-radio 无 button 形态;
|
|
19
|
-
* 这里复用 Radio 渲染(功能可用,视觉非按钮)。
|
|
20
|
-
*/
|
|
31
|
+
/** Radio.Button —— 按钮形态变体。hb-radio 无 button 形态,复用 Radio(功能可用)。 */
|
|
21
32
|
Radio.Button = function RadioButton(props) {
|
|
22
33
|
return _jsx(Radio, { ...props });
|
|
23
34
|
};
|
package/lib/components/Rate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbRate } from '@huibo-ui/react';
|
|
3
3
|
export function Rate(props) {
|
|
4
|
-
return _jsx(HbRate, { modelValue: props.value ?? 0, max: props.count ?? 5, allowHalf: props.allowHalf, disabled: props.disabled, onHbChange: (e) => props.onChange?.(e.detail), style: props.style });
|
|
4
|
+
return (_jsx(HbRate, { modelValue: props.value ?? 0, max: props.count ?? 5, allowHalf: props.allowHalf, disabled: props.disabled, onHbChange: (e) => props.onChange?.(e.detail), style: props.style }));
|
|
5
5
|
}
|
package/lib/components/Result.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { HbResult } from '@huibo-ui/react';
|
|
3
3
|
export function Result(props) {
|
|
4
|
-
return _jsxs(HbResult, { status: props.status, title: typeof props.title === 'string' ? props.title : '', subTitle: typeof props.subTitle === 'string' ? props.subTitle : '', children: [props.extra, props.children] });
|
|
4
|
+
return (_jsxs(HbResult, { status: props.status, title: typeof props.title === 'string' ? props.title : '', subTitle: typeof props.subTitle === 'string' ? props.subTitle : '', children: [props.extra, props.children] }));
|
|
5
5
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export declare function Segmented(props: {
|
|
3
|
-
options?: {
|
|
3
|
+
options?: Array<string | {
|
|
4
4
|
value: string;
|
|
5
|
-
label
|
|
6
|
-
|
|
5
|
+
label?: React.ReactNode;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}>;
|
|
7
8
|
value?: string;
|
|
9
|
+
defaultValue?: string;
|
|
8
10
|
onChange?: (value: string) => void;
|
|
9
11
|
block?: boolean;
|
|
10
12
|
size?: 'small' | 'middle' | 'large';
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbSegmented } from '@huibo-ui/react';
|
|
3
3
|
export function Segmented(props) {
|
|
4
|
-
|
|
4
|
+
// antd 允许 options 为字符串数组(['每日','每周'])或对象数组;hb-segmented 只认 {value,label}。
|
|
5
|
+
// 规范化:字符串 → { value: s, label: s },对象保持(label 缺省时用 value 兜底)。
|
|
6
|
+
const normalized = props.options?.map(o => typeof o === 'string' ? { value: o, label: o } : { value: String(o?.value), label: (o?.label ?? String(o?.value)), disabled: o?.disabled });
|
|
7
|
+
return (_jsx(HbSegmented, { options: normalized, modelValue: props.value ?? props.defaultValue, block: props.block, size: props.size === 'middle' ? 'default' : props.size, onHbChange: (e) => props.onChange?.(e.detail) }));
|
|
5
8
|
}
|
package/lib/components/Select.js
CHANGED
|
@@ -27,7 +27,7 @@ function SelectOptionComponent(_props) {
|
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
export function Select(props) {
|
|
30
|
-
const { value, onChange, options, mode, placeholder, disabled, size, allowClear, showSearch, virtual, style, children
|
|
30
|
+
const { value, onChange, options, mode, placeholder, disabled, size, allowClear, showSearch, virtual, style, children } = props;
|
|
31
31
|
// antd maxTagCount:多选时折叠超出数量的 tag。映射到 hb-select 的 collapseTags + maxCollapseTags
|
|
32
32
|
const maxTagCount = props.maxTagCount;
|
|
33
33
|
// antd fieldNames:自定义 option 字段名(如 {label:'nickName', value:'id'})。
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* antd Slider 兼容层。
|
|
4
|
+
* 修复:旧实现 modelValue={props.value ?? 0} 没处理 defaultValue,导致 demo 的
|
|
5
|
+
* defaultValue={30} 不生效、滑块初始永远在 0。同时补上 range 双滑块支持。
|
|
6
|
+
*/
|
|
2
7
|
export declare function Slider(props: {
|
|
3
|
-
value?: number;
|
|
4
|
-
|
|
8
|
+
value?: number | number[];
|
|
9
|
+
defaultValue?: number | number[];
|
|
10
|
+
onChange?: (value: number | number[]) => void;
|
|
5
11
|
min?: number;
|
|
6
12
|
max?: number;
|
|
7
13
|
step?: number;
|
|
8
14
|
disabled?: boolean;
|
|
15
|
+
range?: boolean;
|
|
9
16
|
vertical?: boolean;
|
|
10
17
|
style?: React.CSSProperties;
|
|
11
18
|
}): React.JSX.Element;
|
package/lib/components/Slider.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbSlider } from '@huibo-ui/react';
|
|
3
|
+
/**
|
|
4
|
+
* antd Slider 兼容层。
|
|
5
|
+
* 修复:旧实现 modelValue={props.value ?? 0} 没处理 defaultValue,导致 demo 的
|
|
6
|
+
* defaultValue={30} 不生效、滑块初始永远在 0。同时补上 range 双滑块支持。
|
|
7
|
+
*/
|
|
3
8
|
export function Slider(props) {
|
|
4
|
-
|
|
9
|
+
const isRange = props.range || Array.isArray(props.value) || Array.isArray(props.defaultValue);
|
|
10
|
+
const modelValue = props.value ?? props.defaultValue ?? (isRange ? [0, 100] : 0);
|
|
11
|
+
return (_jsx(HbSlider, { modelValue: modelValue, min: props.min ?? 0, max: props.max ?? 100, step: props.step ?? 1, disabled: props.disabled, range: isRange, vertical: props.vertical, onHbChange: (e) => props.onChange?.(e.detail), style: props.style }));
|
|
5
12
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export declare function Space(props: {
|
|
3
|
-
size?: 'small' | 'middle' | 'large' | number;
|
|
3
|
+
size?: 'small' | 'middle' | 'large' | number | [number, number];
|
|
4
4
|
direction?: 'horizontal' | 'vertical';
|
|
5
5
|
align?: 'start' | 'center' | 'end';
|
|
6
6
|
wrap?: boolean;
|
|
7
7
|
children?: React.ReactNode;
|
|
8
8
|
style?: React.CSSProperties;
|
|
9
|
+
className?: string;
|
|
9
10
|
}): React.JSX.Element;
|
|
10
11
|
export declare namespace Space {
|
|
11
12
|
var Compact: any;
|
package/lib/components/Space.js
CHANGED
|
@@ -1,12 +1,55 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* antd Space 兼容层(纯 div 实现)。
|
|
4
|
+
*
|
|
5
|
+
* 不再走 <HbSpace>(Shadow DOM slot):hb-space 的 ::slotted(*) 会把所有子元素强制
|
|
6
|
+
* display:inline-block + flex-shrink:0,导致塞进来的 <Select>/<DatePicker>/<Input>
|
|
7
|
+
* 宽度锁死、搜索栏等 flex 容器布局错乱。纯 div + flex + gap 是 antd 的真实做法,
|
|
8
|
+
* 子元素作为真实 DOM 参与 flex 流,宽度/伸缩行为与 antd 一致。
|
|
9
|
+
*
|
|
10
|
+
* size 映射 antd:small=8px / middle=16px / large=24px / number=自定义。
|
|
11
|
+
*/
|
|
12
|
+
const SIZE_MAP = {
|
|
13
|
+
small: 8,
|
|
14
|
+
middle: 16,
|
|
15
|
+
large: 24,
|
|
16
|
+
};
|
|
3
17
|
export function Space(props) {
|
|
4
|
-
|
|
18
|
+
const { size = 'small', direction = 'horizontal', align, wrap, children, style, className } = props;
|
|
19
|
+
// antd gutter 支持 [horizontal, vertical] 数组;单值时两向同值。
|
|
20
|
+
let rowGap;
|
|
21
|
+
let columnGap;
|
|
22
|
+
if (Array.isArray(size)) {
|
|
23
|
+
rowGap = size[0];
|
|
24
|
+
columnGap = size[1];
|
|
25
|
+
}
|
|
26
|
+
else if (typeof size === 'number') {
|
|
27
|
+
rowGap = size;
|
|
28
|
+
columnGap = size;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const v = SIZE_MAP[size] ?? 8;
|
|
32
|
+
rowGap = v;
|
|
33
|
+
columnGap = v;
|
|
34
|
+
}
|
|
35
|
+
const isHorizontal = direction === 'horizontal';
|
|
36
|
+
return (_jsx("div", { style: {
|
|
37
|
+
display: 'flex',
|
|
38
|
+
flexDirection: isHorizontal ? 'row' : 'column',
|
|
39
|
+
flexWrap: wrap ? 'wrap' : 'nowrap',
|
|
40
|
+
rowGap,
|
|
41
|
+
columnGap,
|
|
42
|
+
alignItems: align === 'start' ? 'flex-start' : align === 'end' ? 'flex-end' : align === 'center' ? 'center' : undefined,
|
|
43
|
+
...style,
|
|
44
|
+
}, className: className, children: children }));
|
|
5
45
|
}
|
|
6
46
|
/**
|
|
7
47
|
* Space.Compact —— 紧凑布局(antd 子组件)。huibo 无对应形态,
|
|
8
|
-
*
|
|
48
|
+
* 直接 inline-flex 透传 children,子元素间无 gap(紧凑)。
|
|
9
49
|
*/
|
|
10
50
|
Space.Compact = function Compact(props) {
|
|
11
|
-
return _jsx("div", { style: {
|
|
51
|
+
return (_jsx("div", { style: {
|
|
52
|
+
display: props.block ? 'flex' : 'inline-flex',
|
|
53
|
+
...props.style,
|
|
54
|
+
}, className: props.className, children: props.children }));
|
|
12
55
|
};
|