@huibo-ui/react-antd 1.0.11 → 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/Avatar.js +4 -1
- 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 +121 -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/Form.d.ts +25 -14
- package/lib/components/Form.js +307 -95
- 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 +38 -13
- package/lib/components/Menu.js +53 -9
- package/lib/components/Modal.d.ts +4 -1
- package/lib/components/Modal.js +137 -22
- package/lib/components/Radio.d.ts +5 -3
- package/lib/components/Radio.js +24 -13
- package/lib/components/Segmented.d.ts +5 -3
- package/lib/components/Segmented.js +4 -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/Statistic.d.ts +1 -0
- package/lib/components/Statistic.js +5 -1
- package/lib/components/Switch.d.ts +6 -0
- package/lib/components/Switch.js +15 -1
- package/lib/components/Tabs.js +51 -26
- package/lib/components/Tag.d.ts +1 -0
- package/lib/components/Tag.js +6 -2
- package/lib/components/Timeline.js +9 -1
- package/lib/components/TreeSelect.d.ts +2 -0
- package/lib/components/TreeSelect.js +19 -1
- package/lib/components/Typography.js +2 -2
- package/lib/components/Watermark.js +21 -1
- package/package.json +5 -6
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbStatistic } from '@huibo-ui/react';
|
|
3
3
|
export function Statistic(props) {
|
|
4
|
-
|
|
4
|
+
// hb-statistic 用 valuePrefix(非 prefix),且只接受 string。
|
|
5
|
+
// 注意:不能传 `prefix` prop —— 它会命中 HTMLElement 原生只读 getter,抛 "has only a getter"。
|
|
6
|
+
const strPrefix = typeof props.prefix === 'string' ? props.prefix : '';
|
|
7
|
+
const strSuffix = typeof props.suffix === 'string' ? props.suffix : '';
|
|
8
|
+
return (_jsx(HbStatistic, { title: typeof props.title === 'string' ? props.title : '', value: props.value ?? 0, precision: props.precision, valuePrefix: strPrefix, suffix: strSuffix, style: props.style }));
|
|
5
9
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* antd Switch 兼容层。
|
|
4
|
+
* antd 有受控(checked)和非受控(defaultChecked)两种模式;兼容层需同时支持。
|
|
5
|
+
* 之前只读 checked、忽略 defaultChecked,导致 <Switch defaultChecked /> 实际未打开。
|
|
6
|
+
*/
|
|
2
7
|
export declare function Switch(props: {
|
|
3
8
|
checked?: boolean;
|
|
9
|
+
defaultChecked?: boolean;
|
|
4
10
|
onChange?: (checked: boolean) => void;
|
|
5
11
|
disabled?: boolean;
|
|
6
12
|
size?: 'small' | 'middle' | 'large';
|
package/lib/components/Switch.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { HbSwitch } from '@huibo-ui/react';
|
|
4
|
+
/**
|
|
5
|
+
* antd Switch 兼容层。
|
|
6
|
+
* antd 有受控(checked)和非受控(defaultChecked)两种模式;兼容层需同时支持。
|
|
7
|
+
* 之前只读 checked、忽略 defaultChecked,导致 <Switch defaultChecked /> 实际未打开。
|
|
8
|
+
*/
|
|
3
9
|
export function Switch(props) {
|
|
4
|
-
|
|
10
|
+
// 非受控:用内部 state 跟踪,初始值取 defaultChecked。
|
|
11
|
+
const isControlled = props.checked !== undefined;
|
|
12
|
+
const [inner, setInner] = React.useState(props.defaultChecked ?? false);
|
|
13
|
+
const value = isControlled ? props.checked : inner;
|
|
14
|
+
return (_jsx(HbSwitch, { modelValue: value, disabled: props.disabled || props.loading, size: props.size === 'middle' ? 'default' : props.size, activeText: props.checkedChildren, inactiveText: props.unCheckedChildren, onHbChange: (e) => {
|
|
15
|
+
if (!isControlled)
|
|
16
|
+
setInner(e.detail);
|
|
17
|
+
props.onChange?.(e.detail);
|
|
18
|
+
} }));
|
|
5
19
|
}
|
package/lib/components/Tabs.js
CHANGED
|
@@ -17,7 +17,36 @@ export function Tabs(props) {
|
|
|
17
17
|
const card = type === 'card';
|
|
18
18
|
const fontSize = size === 'large' ? 16 : size === 'small' ? 13 : 14;
|
|
19
19
|
const tabPadding = size === 'large' ? '16px 24px' : size === 'small' ? '8px 16px' : '12px 16px';
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* 滑动 ink bar(对齐 antd,修复 #18):
|
|
22
|
+
* 修复前每个 tab 各自按 active 条件渲染一个无 transition 的下划线,切换时瞬变;
|
|
23
|
+
* 现在用单一绝对定位 ink bar,位置/宽度由当前 active tab 的 offset 测量驱动,
|
|
24
|
+
* 切换时 transform/width 平滑过渡(滑动效果)。
|
|
25
|
+
*/
|
|
26
|
+
const tabRefs = React.useRef({});
|
|
27
|
+
const navRef = React.useRef(null);
|
|
28
|
+
const [ink, setInk] = React.useState({ offset: 0, size: 0, ready: false });
|
|
29
|
+
const measureInk = React.useCallback(() => {
|
|
30
|
+
const el = tabRefs.current[current] ?? null;
|
|
31
|
+
const nav = navRef.current;
|
|
32
|
+
if (!el || !nav)
|
|
33
|
+
return;
|
|
34
|
+
// 水平:左偏移与宽度;垂直:上偏移与高度
|
|
35
|
+
if (vertical) {
|
|
36
|
+
setInk({ offset: el.offsetTop, size: el.offsetHeight, ready: true });
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
setInk({ offset: el.offsetLeft, size: el.offsetWidth, ready: true });
|
|
40
|
+
}
|
|
41
|
+
}, [current, vertical]);
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
measureInk();
|
|
44
|
+
}, [measureInk, list.length, tabPosition]);
|
|
45
|
+
const inkStyle = vertical
|
|
46
|
+
? { position: 'absolute', left: 0, top: ink.offset, height: ink.size, width: 2, background: PRIMARY, transition: 'top 0.3s cubic-bezier(0.645,0.045,0.355,1), height 0.3s' }
|
|
47
|
+
: { position: 'absolute', left: ink.offset, bottom: 0, width: ink.size, height: 2, background: PRIMARY, transition: 'left 0.3s cubic-bezier(0.645,0.045,0.355,1), width 0.3s' };
|
|
48
|
+
const tabBar = (_jsxs("div", { ref: navRef, style: {
|
|
49
|
+
position: 'relative',
|
|
21
50
|
display: 'flex',
|
|
22
51
|
flexDirection: vertical ? 'column' : 'row',
|
|
23
52
|
borderBottom: vertical || card ? 'none' : '1px solid #f0f0f0',
|
|
@@ -25,31 +54,27 @@ export function Tabs(props) {
|
|
|
25
54
|
gap: vertical ? 0 : 4,
|
|
26
55
|
overflowX: vertical ? 'visible' : 'auto',
|
|
27
56
|
scrollbarWidth: 'thin',
|
|
28
|
-
}, children: list.map(it => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
[vertical ? 'height' : 'width']: '100%',
|
|
50
|
-
background: PRIMARY,
|
|
51
|
-
} }))] }, it.key));
|
|
52
|
-
}) }));
|
|
57
|
+
}, children: [!card && ink.ready && _jsx("span", { style: inkStyle, "aria-hidden": "true" }), list.map(it => {
|
|
58
|
+
const active = it.key === current;
|
|
59
|
+
return (_jsx("div", { ref: el => {
|
|
60
|
+
tabRefs.current[it.key] = el;
|
|
61
|
+
}, role: "tab", "aria-selected": active, onClick: () => select(it.key, it.disabled), style: {
|
|
62
|
+
padding: tabPadding,
|
|
63
|
+
cursor: it.disabled ? 'not-allowed' : 'pointer',
|
|
64
|
+
color: it.disabled ? 'rgba(0,0,0,0.25)' : active ? PRIMARY : 'rgba(0,0,0,0.88)',
|
|
65
|
+
fontWeight: active ? 500 : 400,
|
|
66
|
+
fontSize,
|
|
67
|
+
whiteSpace: 'nowrap',
|
|
68
|
+
position: 'relative',
|
|
69
|
+
zIndex: 1,
|
|
70
|
+
background: card ? (active ? '#fff' : 'transparent') : 'transparent',
|
|
71
|
+
border: card ? '1px solid #f0f0f0' : 'none',
|
|
72
|
+
[vertical ? 'borderBottom' : 'borderBottom']: card ? (active ? '1px solid #fff' : '1px solid #f0f0f0') : 'none',
|
|
73
|
+
marginBottom: card && !vertical ? '-1px' : undefined,
|
|
74
|
+
borderRadius: card ? (vertical ? '4px 0 0 4px' : '4px 4px 0 0') : undefined,
|
|
75
|
+
transition: 'color .2s',
|
|
76
|
+
}, children: it.label }, it.key));
|
|
77
|
+
})] }));
|
|
53
78
|
// 对齐 antd Tabs 默认的渲染策略:
|
|
54
79
|
// - destroyInactiveTabPane=true:只渲染当前 active(切换即销毁旧的)
|
|
55
80
|
// - 默认(lazy keep-alive):只渲染「当前 active」和「曾经 active 过」的;
|
package/lib/components/Tag.d.ts
CHANGED
package/lib/components/Tag.js
CHANGED
|
@@ -4,7 +4,7 @@ const colorMap = {
|
|
|
4
4
|
success: 'success',
|
|
5
5
|
processing: 'info',
|
|
6
6
|
error: 'danger',
|
|
7
|
-
default: '
|
|
7
|
+
default: 'default',
|
|
8
8
|
warning: 'warning',
|
|
9
9
|
blue: 'primary',
|
|
10
10
|
green: 'success',
|
|
@@ -12,5 +12,9 @@ const colorMap = {
|
|
|
12
12
|
orange: 'warning',
|
|
13
13
|
};
|
|
14
14
|
export function Tag(props) {
|
|
15
|
-
|
|
15
|
+
// antd color 既支持预设色名也支持任意 CSS 色(#hex / rgb)。
|
|
16
|
+
// 预设色名 → 映射成 hb-tag type;任意 hex/rgb → 传给 hb-tag 的 color prop(自定义色,由底层渲染)。
|
|
17
|
+
// bordered 默认 true(对齐 antd),透传给 hb-tag。
|
|
18
|
+
const isPreset = props.color && colorMap[props.color];
|
|
19
|
+
return (_jsx(HbTag, { type: isPreset ? colorMap[props.color] : 'default', color: isPreset ? undefined : props.color, closable: props.closable, bordered: props.bordered ?? true, onHbClose: () => props.onClose?.(), style: props.style, children: props.children }));
|
|
16
20
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbTimeline } from '@huibo-ui/react';
|
|
3
3
|
export function Timeline(props) {
|
|
4
|
-
|
|
4
|
+
// hb-timeline 的 item 用 { content, time?, color? };antd 用 { children, label, color }。
|
|
5
|
+
// 兼容层把 antd 的 children/label 映射到 content(取字符串),color 透传,
|
|
6
|
+
// 否则 items 透传后 hb-timeline 取不到 content,时间线文字为空。
|
|
7
|
+
const mapped = props.items?.map(it => ({
|
|
8
|
+
content: typeof it?.children === 'string' ? it.children : typeof it?.label === 'string' ? it.label : '',
|
|
9
|
+
time: typeof it?.time === 'string' ? it.time : undefined,
|
|
10
|
+
color: it?.color,
|
|
11
|
+
}));
|
|
12
|
+
return _jsx(HbTimeline, { items: mapped, direction: props.mode, reverse: props.reverse });
|
|
5
13
|
}
|
|
@@ -2,10 +2,12 @@ import React from 'react';
|
|
|
2
2
|
export declare function TreeSelect(props: {
|
|
3
3
|
treeData?: any[];
|
|
4
4
|
value?: any;
|
|
5
|
+
defaultValue?: any;
|
|
5
6
|
onChange?: (value: any) => void;
|
|
6
7
|
multiple?: boolean;
|
|
7
8
|
treeCheckable?: boolean;
|
|
8
9
|
placeholder?: string;
|
|
9
10
|
disabled?: boolean;
|
|
10
11
|
style?: React.CSSProperties;
|
|
12
|
+
children?: React.ReactNode;
|
|
11
13
|
}): React.JSX.Element;
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbTreeSelect } from '@huibo-ui/react';
|
|
3
|
+
/**
|
|
4
|
+
* 把 antd treeData(字段 value/title/children/disabled)归一化成 hb-tree-select 需要的
|
|
5
|
+
* key/title/children/disabled。hb-tree-select 内部用 node.key 标识节点(渲染 data-tree-key),
|
|
6
|
+
* antd treeData 用 value。修复前直接透传 treeData,hb 取 node.key 得到 undefined,
|
|
7
|
+
* 导致 data-tree-key 缺失、点击节点选中失效(modelValue 用 undefined 比较)、子节点选不中。
|
|
8
|
+
*/
|
|
9
|
+
function normalizeTreeData(nodes) {
|
|
10
|
+
return (nodes || []).map(n => {
|
|
11
|
+
const out = {
|
|
12
|
+
key: n.key !== undefined ? String(n.key) : n.value !== undefined ? String(n.value) : n.title,
|
|
13
|
+
title: n.title ?? n.label,
|
|
14
|
+
disabled: !!n.disabled,
|
|
15
|
+
};
|
|
16
|
+
if (n.children && n.children.length > 0)
|
|
17
|
+
out.children = normalizeTreeData(n.children);
|
|
18
|
+
return out;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
3
21
|
export function TreeSelect(props) {
|
|
4
|
-
return (_jsx(HbTreeSelect, { data: props.treeData || [], modelValue: props.value, multiple: props.multiple || props.treeCheckable, checkable: props.treeCheckable, placeholder: props.placeholder, disabled: props.disabled, onHbChange: (e) => props.onChange?.(e.detail), style: props.style }));
|
|
22
|
+
return (_jsx(HbTreeSelect, { data: normalizeTreeData(props.treeData || []), modelValue: props.value ?? props.defaultValue ?? '', multiple: props.multiple || props.treeCheckable, checkable: props.treeCheckable, placeholder: props.placeholder, disabled: props.disabled, onHbChange: (e) => props.onChange?.(e.detail), style: props.style, children: props.children }));
|
|
5
23
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { HbLink } from '@huibo-ui/react';
|
|
4
3
|
export function Typography(props) {
|
|
5
4
|
return _jsx(_Fragment, { children: props.children });
|
|
6
5
|
}
|
|
@@ -12,7 +11,8 @@ Typography.Paragraph = function Paragraph(props) {
|
|
|
12
11
|
return _jsx("p", { children: props.children });
|
|
13
12
|
};
|
|
14
13
|
Typography.Link = function Link(props) {
|
|
15
|
-
|
|
14
|
+
const { href, children, target, onClick, style, className, ...rest } = props;
|
|
15
|
+
return (_jsx("a", { href: href, target: target, onClick: onClick, style: { color: 'var(--hb-color-primary)', textDecoration: 'none', cursor: 'pointer', ...style }, className: className, ...rest, children: children }));
|
|
16
16
|
};
|
|
17
17
|
Typography.Text = function Text(props) {
|
|
18
18
|
return (_jsx("span", { style: {
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HbWatermark } from '@huibo-ui/react';
|
|
3
3
|
export function Watermark(props) {
|
|
4
|
-
|
|
4
|
+
// 仅传递显式提供的 props:底层 hb-watermark 的 @Prop 带默认值
|
|
5
|
+
// (width=120 / height=120 / gap=8 / rotate=-22 / fontSize=14 / fontColor),
|
|
6
|
+
// 若此处把 undefined 透传给 HbWatermark,React 兼容层的 attachProps 会执行
|
|
7
|
+
// `node.width = undefined` 覆盖 Stencil 默认值,导致 SVG 取到 undefined、
|
|
8
|
+
// backgroundSize 缺失,水印完全不显示。
|
|
9
|
+
const { content, width, height, gap, rotate, font, children } = props;
|
|
10
|
+
const layerProps = { content: content || '' };
|
|
11
|
+
if (width !== undefined)
|
|
12
|
+
layerProps.width = width;
|
|
13
|
+
if (height !== undefined)
|
|
14
|
+
layerProps.height = height;
|
|
15
|
+
const gapValue = Array.isArray(gap) ? gap[0] : gap;
|
|
16
|
+
if (gapValue !== undefined)
|
|
17
|
+
layerProps.gap = gapValue;
|
|
18
|
+
if (rotate !== undefined)
|
|
19
|
+
layerProps.rotate = rotate;
|
|
20
|
+
if (font?.color !== undefined)
|
|
21
|
+
layerProps.fontColor = font.color;
|
|
22
|
+
if (font?.fontSize !== undefined)
|
|
23
|
+
layerProps.fontSize = font.fontSize;
|
|
24
|
+
return _jsx(HbWatermark, { ...layerProps, children: children });
|
|
5
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huibo-ui/react-antd",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "antd 兼容层 — 接收 antd 原生 props,内部转换为 huibo-ui,实现丝滑平替",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -9,10 +9,6 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"lib"
|
|
11
11
|
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "tsc --outDir lib || true",
|
|
14
|
-
"prepublishOnly": "pnpm run build"
|
|
15
|
-
},
|
|
16
12
|
"peerDependencies": {
|
|
17
13
|
"react": ">=16.8.0",
|
|
18
14
|
"react-dom": ">=16.8.0",
|
|
@@ -29,5 +25,8 @@
|
|
|
29
25
|
},
|
|
30
26
|
"publishConfig": {
|
|
31
27
|
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc --outDir lib || true"
|
|
32
31
|
}
|
|
33
|
-
}
|
|
32
|
+
}
|