@tendaui/components 1.0.0 → 1.0.2
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 -21
- package/README.md +176 -176
- package/alert/Alert.tsx +3 -2
- package/button/_example/base.tsx +10 -0
- package/button/_example/icon.tsx +20 -0
- package/color-picker/ColorPickPanel.tsx +9 -0
- package/color-picker/ColorPicker.tsx +67 -0
- package/color-picker/components/panel/alpha.tsx +32 -0
- package/color-picker/components/panel/format/index.tsx +47 -0
- package/color-picker/components/panel/format/inputs.tsx +119 -0
- package/color-picker/components/panel/header.tsx +37 -0
- package/color-picker/components/panel/hue.tsx +20 -0
- package/color-picker/components/panel/index.tsx +191 -0
- package/color-picker/components/panel/saturation.tsx +81 -0
- package/color-picker/components/panel/slider.tsx +76 -0
- package/color-picker/components/panel/swatches.tsx +84 -0
- package/color-picker/components/trigger.tsx +49 -0
- package/color-picker/defaultProps.ts +7 -0
- package/color-picker/helpers.ts +53 -0
- package/color-picker/hooks/useClassNames.ts +9 -0
- package/color-picker/hooks/useStyles.ts +39 -0
- package/color-picker/index.ts +12 -0
- package/color-picker/style/css.js +1 -0
- package/color-picker/style/index.js +1 -0
- package/color-picker/type.ts +143 -0
- package/color-picker/utils/color-picker/cmyk.ts +89 -0
- package/color-picker/utils/color-picker/color.ts +467 -0
- package/color-picker/utils/color-picker/constants.ts +187 -0
- package/color-picker/utils/color-picker/draggable.ts +100 -0
- package/color-picker/utils/color-picker/format.ts +95 -0
- package/color-picker/utils/color-picker/gradient.ts +243 -0
- package/color-picker/utils/color-picker/index.ts +7 -0
- package/color-picker/utils/color-picker/types.ts +33 -0
- package/common/observe.ts +33 -0
- package/common.ts +20 -0
- package/config-provider/ConfigContext.tsx +4 -1
- package/config-provider/index.ts +1 -1
- package/dialog/DialogCard.tsx +4 -6
- package/dialog/hooks/useDialogPosition.ts +1 -2
- package/dialog/plugin.tsx +3 -2
- package/drawer/Drawer.tsx +264 -0
- package/drawer/defaultProps.ts +19 -0
- package/drawer/hooks/useDrag.ts +98 -0
- package/drawer/hooks/useLockStyle.ts +36 -0
- package/drawer/index.ts +5 -0
- package/drawer/style/css.js +1 -0
- package/drawer/style/index.js +1 -0
- package/drawer/type.ts +193 -0
- package/drawer/utils/index.ts +76 -0
- package/fireworks/Fireworks.tsx +138 -0
- package/fireworks/index.ts +10 -0
- package/fireworks/style/css.js +0 -0
- package/fireworks/style/index.js +0 -0
- package/fireworks/type.ts +72 -0
- package/form/FormItem.tsx +5 -5
- package/form/easing.ts +10 -0
- package/form/scroll.ts +124 -0
- package/form/type.ts +519 -519
- package/global-config/default-config.ts +95 -0
- package/global-config/locale/ar_KW.ts +270 -0
- package/global-config/locale/en_US.ts +280 -0
- package/global-config/locale/it_IT.ts +287 -0
- package/global-config/locale/ja_JP.ts +279 -0
- package/global-config/locale/ko_KR.ts +279 -0
- package/global-config/locale/ru_RU.ts +288 -0
- package/global-config/locale/zh_CN.ts +279 -0
- package/global-config/locale/zh_TW.ts +279 -0
- package/global-config/mobile/default-config.ts +6 -0
- package/global-config/mobile/locale/ar_KW.ts +113 -0
- package/global-config/mobile/locale/en_US.ts +114 -0
- package/global-config/mobile/locale/it_IT.ts +114 -0
- package/global-config/mobile/locale/ja_JP.ts +101 -0
- package/global-config/mobile/locale/ko_KR.ts +101 -0
- package/global-config/mobile/locale/ru_RU.ts +113 -0
- package/global-config/mobile/locale/zh_CN.ts +101 -0
- package/global-config/mobile/locale/zh_TW.ts +101 -0
- package/global-config/t.ts +111 -0
- package/hooks/useControlled.ts +3 -3
- package/hooks/useDeepEffect.ts +32 -0
- package/hooks/useGlobalIcon.ts +10 -3
- package/hooks/useLastest.ts +2 -6
- package/hooks/useResizeObserve.ts +36 -0
- package/index.ts +10 -7
- package/input/Input.tsx +4 -1
- package/input/defaultProps.ts +0 -2
- package/input/type.ts +1 -6
- package/input-number/InputNumber.tsx +124 -0
- package/input-number/defaultProps.ts +17 -0
- package/input-number/index.ts +9 -0
- package/input-number/style/css.js +1 -0
- package/input-number/style/index.js +1 -0
- package/input-number/type.ts +147 -0
- package/input-number/useInputNumber.tsx +270 -0
- package/ip-input/IPInput.tsx +516 -0
- package/ip-input/defaultProps.ts +11 -0
- package/ip-input/index.ts +3 -0
- package/ip-input/style/css.js +1 -0
- package/ip-input/style/index.js +1 -0
- package/ip-input/type.ts +115 -0
- package/ip-input/utils.ts +112 -0
- package/layout/Aside.tsx +38 -0
- package/layout/Layout.tsx +104 -0
- package/layout/defaultProps.ts +9 -0
- package/layout/index.ts +9 -0
- package/layout/style/css.js +1 -0
- package/layout/style/index.js +1 -0
- package/layout/type.ts +43 -0
- package/list/List.tsx +144 -0
- package/list/ListItem.tsx +36 -0
- package/list/ListItemMeta.tsx +40 -0
- package/list/defaultProps.ts +11 -0
- package/list/hooks/useListVirtualScroll.ts +82 -0
- package/list/index.ts +11 -0
- package/list/style/css.js +1 -0
- package/list/style/index.js +1 -0
- package/list/type.ts +93 -0
- package/locale/LocalReceiver.ts +55 -0
- package/locale/ar_KW.ts +7 -0
- package/locale/en_US.ts +7 -0
- package/locale/it_IT.ts +6 -0
- package/locale/ja_JP.ts +6 -0
- package/locale/ko_KR.ts +6 -0
- package/locale/ru_RU.ts +6 -0
- package/locale/zh_CN.ts +5 -0
- package/locale/zh_TW.ts +7 -0
- package/notification/NotifyContainer.tsx +2 -2
- package/notification/NotifyContext.tsx +1 -0
- package/package.json +6 -3
- package/popup/Popup.tsx +34 -10
- package/radio/Radio.tsx +24 -0
- package/radio/RadioGroup.tsx +159 -0
- package/radio/defaultProps.ts +18 -0
- package/radio/index.ts +12 -0
- package/radio/style/css.js +0 -0
- package/radio/style/index.js +1 -0
- package/radio/type.ts +115 -0
- package/radio/useKeyboard.ts +36 -0
- package/select/hooks/useOptions.ts +10 -7
- package/select/hooks/usePanelVirtualScroll.ts +1 -1
- package/select/type.ts +382 -382
- package/select-input/type.ts +280 -280
- package/slider/Slider.tsx +270 -0
- package/slider/SliderHandleButton.tsx +50 -0
- package/slider/defaultProps.ts +15 -0
- package/slider/index.ts +9 -0
- package/slider/style/css.js +1 -0
- package/slider/style/index.js +1 -0
- package/slider/type.ts +77 -0
- package/style/all.js +26 -0
- package/styles/_global.scss +39 -39
- package/styles/_vars.scss +358 -386
- package/styles/components/alert/_index.scss +175 -175
- package/styles/components/alert/_vars.scss +39 -39
- package/styles/components/badge/_index.scss +70 -70
- package/styles/components/badge/_vars.scss +25 -25
- package/styles/components/button/_index.scss +499 -511
- package/styles/components/button/_mixins.scss +39 -39
- package/styles/components/button/_vars.scss +120 -122
- package/styles/components/checkbox/_index.scss +158 -158
- package/styles/components/checkbox/_var.scss +60 -60
- package/styles/components/color-picker/_index.scss +586 -0
- package/styles/components/color-picker/_mixins.scss +0 -0
- package/styles/components/color-picker/_vars.scss +84 -0
- package/styles/components/dialog/_animate.scss +135 -135
- package/styles/components/dialog/_index.scss +311 -311
- package/styles/components/dialog/_vars.scss +59 -59
- package/styles/components/drawer/_index.scss +205 -0
- package/styles/components/drawer/_mixins.scss +1 -0
- package/styles/components/drawer/_var.scss +53 -0
- package/styles/components/fireworks/_index.scss +86 -0
- package/styles/components/fireworks/_vars.scss +4 -0
- package/styles/components/form/_index.scss +174 -174
- package/styles/components/form/_mixins.scss +76 -76
- package/styles/components/form/_vars.scss +100 -100
- package/styles/components/input/_index.scss +349 -349
- package/styles/components/input/_mixins.scss +116 -116
- package/styles/components/input/_vars.scss +134 -134
- package/styles/components/input-number/_index.scss +353 -0
- package/styles/components/input-number/_mixins.scss +0 -0
- package/styles/components/input-number/_vars.scss +65 -0
- package/styles/components/ip-input/_index.scss +280 -0
- package/styles/components/layout/_index.scss +47 -0
- package/styles/components/layout/_mixin.scss +0 -0
- package/styles/components/layout/_vars.scss +18 -0
- package/styles/components/layout/doc.scss +74 -0
- package/styles/components/list/_index.scss +172 -0
- package/styles/components/list/_mixins.scss +0 -0
- package/styles/components/list/_vars.scss +41 -0
- package/styles/components/loading/_index.scss +112 -112
- package/styles/components/loading/_vars.scss +39 -39
- package/styles/components/notification/_index.scss +160 -160
- package/styles/components/notification/_mixins.scss +12 -12
- package/styles/components/notification/_vars.scss +59 -59
- package/styles/components/popup/_index.scss +82 -82
- package/styles/components/popup/_mixin.scss +149 -149
- package/styles/components/popup/_var.scss +31 -31
- package/styles/components/radio/_index.scss +376 -0
- package/styles/components/radio/_mixins.scss +0 -0
- package/styles/components/radio/_var.scss +92 -0
- package/styles/components/select/_index.scss +290 -290
- package/styles/components/select/_var.scss +65 -65
- package/styles/components/select-input/_index.scss +5 -5
- package/styles/components/select-input/_var.scss +3 -3
- package/styles/components/slider/_index.scss +241 -0
- package/styles/components/slider/_mixins.scss +0 -0
- package/styles/components/slider/_vars.scss +50 -0
- package/styles/components/switch/_index.scss +279 -279
- package/styles/components/switch/_vars.scss +61 -61
- package/styles/components/table/_index.scss +193 -0
- package/styles/components/table/_var.scss +52 -0
- package/styles/components/tabs/_index.scss +165 -0
- package/styles/components/tabs/_mixins.scss +11 -0
- package/styles/components/tabs/_vars.scss +71 -0
- package/styles/components/tag/_index.scss +316 -316
- package/styles/components/tag/_var.scss +85 -85
- package/styles/components/tag-input/_index.scss +163 -163
- package/styles/components/tag-input/_vars.scss +16 -16
- package/styles/globals.css +250 -250
- package/styles/mixins/_focus.scss +7 -7
- package/styles/mixins/_layout.scss +32 -32
- package/styles/mixins/_reset.scss +10 -10
- package/styles/mixins/_scrollbar.scss +31 -31
- package/styles/mixins/_text.scss +48 -48
- package/styles/rillple.css +16 -16
- package/styles/scrollbar.css +41 -41
- package/styles/themes/_dark.scss +191 -191
- package/styles/themes/_font.scss +69 -79
- package/styles/themes/_index.scss +5 -5
- package/styles/themes/_light.scss +190 -190
- package/styles/themes/_radius.scss +9 -9
- package/styles/themes/_size.scss +68 -68
- package/styles/themes.css +66 -66
- package/styles/utilities/_animation.scss +57 -57
- package/styles/utilities/_tips.scss +9 -9
- package/tab/TabBar.tsx +85 -0
- package/tab/TabNav.tsx +103 -0
- package/tab/TabNavItem.tsx +80 -0
- package/tab/TabPanel.tsx +42 -0
- package/tab/Tabs.tsx +71 -0
- package/tab/defaultProps.ts +19 -0
- package/tab/index.ts +7 -0
- package/tab/style/index.js +1 -0
- package/tab/type.ts +125 -0
- package/tab/useTabClass.ts +20 -0
- package/table/Cell.tsx +109 -0
- package/table/TBody.tsx +77 -0
- package/table/THead.tsx +63 -0
- package/table/TR.tsx +78 -0
- package/table/Table.tsx +73 -0
- package/table/defaultProps.ts +14 -0
- package/table/hooks/index.ts +4 -0
- package/table/hooks/useTableClassName.ts +63 -0
- package/table/hooks/useTableStyle.ts +93 -0
- package/table/index.ts +7 -0
- package/table/style/css.js +1 -0
- package/table/style/index.js +1 -0
- package/table/type.ts +192 -0
- package/tag/Tag.tsx +1 -1
- package/tag-input/hooks/useTagList.tsx +1 -1
- package/utils/dom.ts +4 -0
- package/utils/forwardRefWithStatics.ts +1 -4
- package/utils/input-number/large-number.ts +423 -0
- package/utils/input-number/number.ts +257 -0
- package/utils/isFragment.ts +6 -6
- package/utils/log/index.ts +3 -0
- package/utils/log/log.ts +30 -0
- package/utils/log/types.ts +12 -0
- package/utils/number.ts +21 -0
- package/utils/scroll.ts +26 -0
- package/utils/style.ts +2 -4
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IP 地址验证和解析工具函数
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 验证 IPv4 地址段(0-255)
|
|
7
|
+
*/
|
|
8
|
+
export function isValidIPv4Segment(segment: string, allowLeadingZeros: boolean = false): boolean {
|
|
9
|
+
if (!segment || segment.trim() === "") return false;
|
|
10
|
+
|
|
11
|
+
// 不允许前导零
|
|
12
|
+
if (!allowLeadingZeros && segment.length > 1 && segment[0] === "0") {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const num = parseInt(segment, 10);
|
|
17
|
+
return !isNaN(num) && num >= 0 && num <= 255 && num.toString() === segment;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 验证 IPv4 地址
|
|
22
|
+
*/
|
|
23
|
+
export function isValidIPv4(ip: string, allowLeadingZeros: boolean = false): boolean {
|
|
24
|
+
if (!ip || typeof ip !== "string") return false;
|
|
25
|
+
|
|
26
|
+
const segments = ip.split(".");
|
|
27
|
+
if (segments.length !== 4) return false;
|
|
28
|
+
|
|
29
|
+
return segments.every((seg) => isValidIPv4Segment(seg, allowLeadingZeros));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 验证 CIDR 掩码(IPv4: 0-32, IPv6: 0-128)
|
|
34
|
+
*/
|
|
35
|
+
export function isValidCIDRMask(mask: string, isIPv6: boolean = false): boolean {
|
|
36
|
+
if (!mask || typeof mask !== "string") return false;
|
|
37
|
+
|
|
38
|
+
const num = parseInt(mask, 10);
|
|
39
|
+
if (isNaN(num)) return false;
|
|
40
|
+
|
|
41
|
+
const max = isIPv6 ? 128 : 32;
|
|
42
|
+
return num >= 0 && num <= max;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 验证 IPv6 地址(简化版,使用正则)
|
|
47
|
+
* 支持压缩表示法 :: 和混合 IPv4/IPv6
|
|
48
|
+
*/
|
|
49
|
+
export function isValidIPv6(ip: string): boolean {
|
|
50
|
+
if (!ip || typeof ip !== "string") return false;
|
|
51
|
+
|
|
52
|
+
// 简化的 IPv6 验证正则
|
|
53
|
+
// 支持:
|
|
54
|
+
// - 标准格式:2001:0db8:85a3:0000:0000:8a2e:0370:7334
|
|
55
|
+
// - 压缩格式:2001:db8::1
|
|
56
|
+
// - 混合格式:::ffff:192.168.0.1
|
|
57
|
+
const ipv6Regex =
|
|
58
|
+
/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
|
|
59
|
+
|
|
60
|
+
return ipv6Regex.test(ip);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 从文本中提取 IP 地址
|
|
65
|
+
*/
|
|
66
|
+
export function extractIPFromText(text: string): { ip: string; cidr?: string } | null {
|
|
67
|
+
if (!text || typeof text !== "string") return null;
|
|
68
|
+
|
|
69
|
+
// 尝试提取 IPv4
|
|
70
|
+
const ipv4Regex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:\/(\d{1,2}))?/;
|
|
71
|
+
const ipv4Match = text.match(ipv4Regex);
|
|
72
|
+
if (ipv4Match) {
|
|
73
|
+
const ip = ipv4Match[1];
|
|
74
|
+
const cidr = ipv4Match[2];
|
|
75
|
+
if (isValidIPv4(ip, true)) {
|
|
76
|
+
return { ip, cidr };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 尝试提取 IPv6
|
|
81
|
+
const ipv6Regex = /([0-9a-fA-F:]+(?::[0-9a-fA-F:]+)*|::)(?:\/(\d{1,3}))?/;
|
|
82
|
+
const ipv6Match = text.match(ipv6Regex);
|
|
83
|
+
if (ipv6Match) {
|
|
84
|
+
const ip = ipv6Match[1];
|
|
85
|
+
const cidr = ipv6Match[2];
|
|
86
|
+
if (isValidIPv6(ip)) {
|
|
87
|
+
return { ip, cidr };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 解析 IP 地址为段数组(IPv4)
|
|
96
|
+
*/
|
|
97
|
+
export function parseIPv4ToSegments(ip: string): string[] {
|
|
98
|
+
if (!ip) return ["", "", "", ""];
|
|
99
|
+
const segments = ip.split(".");
|
|
100
|
+
return [segments[0] || "", segments[1] || "", segments[2] || "", segments[3] || ""];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 将段数组组合为 IP 地址(IPv4)
|
|
105
|
+
*/
|
|
106
|
+
export function segmentsToIPv4(segments: string[]): string {
|
|
107
|
+
// 如果所有段都为空,返回空字符串
|
|
108
|
+
if (segments.every((seg) => !seg || seg.trim() === "")) {
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
return segments.join(".");
|
|
112
|
+
}
|
package/layout/Aside.tsx
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import useConfig from "../hooks/useConfig";
|
|
4
|
+
import { TdAsideProps } from "./type";
|
|
5
|
+
import { StyledProps } from "../common";
|
|
6
|
+
import useDefaultProps from "../hooks/useDefaultProps";
|
|
7
|
+
export interface AsideProps extends TdAsideProps, StyledProps {
|
|
8
|
+
/**
|
|
9
|
+
* 文本内容
|
|
10
|
+
*/
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const Aside: React.FC<AsideProps> = (props) => {
|
|
15
|
+
const { width, className, style, children, ...otherAsideProps } = useDefaultProps(props, { width: "232px" });
|
|
16
|
+
|
|
17
|
+
const { classPrefix } = useConfig();
|
|
18
|
+
const asideClassNames = classNames(`${classPrefix}-layout__sider`, className);
|
|
19
|
+
const asideWidth: string = typeof width === "number" ? `${width}px` : width;
|
|
20
|
+
|
|
21
|
+
const asideStyle: React.CSSProperties = {
|
|
22
|
+
width: asideWidth,
|
|
23
|
+
maxWidth: asideWidth,
|
|
24
|
+
minWidth: asideWidth,
|
|
25
|
+
flex: `0 0 ${asideWidth}`,
|
|
26
|
+
...style
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<aside className={asideClassNames} style={asideStyle} {...otherAsideProps}>
|
|
31
|
+
{children}
|
|
32
|
+
</aside>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
Aside.displayName = "Aside";
|
|
37
|
+
|
|
38
|
+
export default Aside;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import useConfig from "../hooks/useConfig";
|
|
4
|
+
import { StyledProps } from "../common";
|
|
5
|
+
import { TdLayoutProps, TdHeaderProps, TdFooterProps } from "./type";
|
|
6
|
+
import { useMemo } from "react";
|
|
7
|
+
import Aside from "./Aside";
|
|
8
|
+
import parseTNode from "../utils/parseTNode";
|
|
9
|
+
export interface LayoutProps extends TdLayoutProps, StyledProps, React.HTMLAttributes<HTMLDivElement> {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export interface HeaderProps extends TdHeaderProps, StyledProps, React.HTMLAttributes<HTMLElement> {
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export interface ContentProps extends StyledProps, React.HTMLAttributes<HTMLElement> {
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export interface FooterProps extends TdFooterProps, StyledProps, React.HTMLAttributes<HTMLElement> {
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const Header: React.FC<HeaderProps> = (props) => {
|
|
23
|
+
const { classPrefix } = useConfig();
|
|
24
|
+
const { className, style = {}, children, height, ...others } = props;
|
|
25
|
+
const renderHeight = isNaN(Number(height)) ? height : `${height}px`;
|
|
26
|
+
const headerClassNames = classNames(`${classPrefix}-layout__header`, className);
|
|
27
|
+
return (
|
|
28
|
+
<header className={headerClassNames} style={{ height: renderHeight, ...style }} {...others}>
|
|
29
|
+
{parseTNode(children)}
|
|
30
|
+
</header>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const Footer: React.FC<FooterProps> = (props) => {
|
|
35
|
+
const { classPrefix } = useConfig();
|
|
36
|
+
const { className, style = {}, children, height, ...others } = props;
|
|
37
|
+
const renderHeight = isNaN(Number(height)) ? height : `${height}px`;
|
|
38
|
+
const footerClassNames = classNames(`${classPrefix}-layout__footer`, className);
|
|
39
|
+
return (
|
|
40
|
+
<footer className={footerClassNames} style={{ height: renderHeight, ...style }} {...others}>
|
|
41
|
+
{parseTNode(children)}
|
|
42
|
+
</footer>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
const Content: React.FC<ContentProps> = (props) => {
|
|
46
|
+
const { classPrefix } = useConfig();
|
|
47
|
+
const { className, style, children, content, ...others } = props;
|
|
48
|
+
const contentClassNames = classNames(`${classPrefix}-layout__content`, className);
|
|
49
|
+
return (
|
|
50
|
+
<main className={contentClassNames} style={style} {...others}>
|
|
51
|
+
{parseTNode(content) || parseTNode(children)}
|
|
52
|
+
</main>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const Layout: React.FC<LayoutProps> & {
|
|
57
|
+
Header: typeof Header;
|
|
58
|
+
Content: typeof Content;
|
|
59
|
+
Footer: typeof Footer;
|
|
60
|
+
Aside: typeof Aside;
|
|
61
|
+
} = (props) => {
|
|
62
|
+
const { direction, className, style, children, ...otherLayoutProps } = props;
|
|
63
|
+
|
|
64
|
+
const shouldAsides = useMemo(() => {
|
|
65
|
+
const asides: React.ReactElement[] = [];
|
|
66
|
+
React.Children.forEach(children, (child: React.ReactElement) => {
|
|
67
|
+
if (!child || typeof child !== "object") {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (child.type === Aside) {
|
|
71
|
+
asides.push(child);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return !!asides.length;
|
|
75
|
+
}, [children]);
|
|
76
|
+
|
|
77
|
+
const { classPrefix } = useConfig();
|
|
78
|
+
const layoutClassNames = classNames(
|
|
79
|
+
`${classPrefix}-layout`,
|
|
80
|
+
{
|
|
81
|
+
[`${classPrefix}-layout--with-sider`]: shouldAsides,
|
|
82
|
+
[`${classPrefix}-layout__direction-${direction}`]: direction
|
|
83
|
+
},
|
|
84
|
+
className
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div className={layoutClassNames} style={style} {...otherLayoutProps}>
|
|
89
|
+
{parseTNode(children)}
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
Layout.Header = Header;
|
|
95
|
+
Layout.Content = Content;
|
|
96
|
+
Layout.Footer = Footer;
|
|
97
|
+
Layout.Aside = Aside;
|
|
98
|
+
|
|
99
|
+
Header.displayName = "Header";
|
|
100
|
+
Content.displayName = "Content";
|
|
101
|
+
Footer.displayName = "Footer";
|
|
102
|
+
Layout.displayName = "Layout";
|
|
103
|
+
|
|
104
|
+
export default Layout;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TdAsideProps, TdFooterProps, TdHeaderProps, TdLayoutProps } from "./type";
|
|
2
|
+
|
|
3
|
+
export const asideDefaultProps: TdAsideProps = {};
|
|
4
|
+
|
|
5
|
+
export const footerDefaultProps: TdFooterProps = {};
|
|
6
|
+
|
|
7
|
+
export const headerDefaultProps: TdHeaderProps = {};
|
|
8
|
+
|
|
9
|
+
export const layoutDefaultProps: TdLayoutProps = {};
|
package/layout/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./index.css";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../../styles/components/layout/_index.scss";
|
package/layout/type.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TNode } from "../common";
|
|
2
|
+
|
|
3
|
+
export interface TdLayoutProps {
|
|
4
|
+
/**
|
|
5
|
+
* 【开发中】布局方向
|
|
6
|
+
*/
|
|
7
|
+
direction?: "vertical" | "horizontal";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface TdHeaderProps {
|
|
11
|
+
/**
|
|
12
|
+
* 顶栏高度。样式表(class)中定义的默认高度为:64px
|
|
13
|
+
* @default ''
|
|
14
|
+
*/
|
|
15
|
+
height?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TdAsideProps {
|
|
19
|
+
/**
|
|
20
|
+
* 侧边栏宽度。样式表(class)中定义的默认宽度为:232px
|
|
21
|
+
* @default ''
|
|
22
|
+
*/
|
|
23
|
+
width?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TdContentProps {
|
|
27
|
+
/**
|
|
28
|
+
* 内容,同 content
|
|
29
|
+
*/
|
|
30
|
+
children?: TNode;
|
|
31
|
+
/**
|
|
32
|
+
* 内容
|
|
33
|
+
*/
|
|
34
|
+
content?: TNode;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface TdFooterProps {
|
|
38
|
+
/**
|
|
39
|
+
* 底栏高度。样式表(class)中定义的默认高度为:24px
|
|
40
|
+
* @default ''
|
|
41
|
+
*/
|
|
42
|
+
height?: string;
|
|
43
|
+
}
|
package/list/List.tsx
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import React, { useImperativeHandle, useMemo, useRef, WheelEvent } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import { compact, isString } from "lodash-es";
|
|
4
|
+
import forwardRefWithStatics from "../utils/forwardRefWithStatics";
|
|
5
|
+
import noop from "../utils/noop";
|
|
6
|
+
import parseTNode from "../utils/parseTNode";
|
|
7
|
+
import useConfig from "../hooks/useConfig";
|
|
8
|
+
import useDefaultProps from "../hooks/useDefaultProps";
|
|
9
|
+
import Loading from "../loading";
|
|
10
|
+
import { useLocaleReceiver } from "../locale/LocalReceiver";
|
|
11
|
+
import ListItem from "./ListItem";
|
|
12
|
+
import ListItemMeta from "./ListItemMeta";
|
|
13
|
+
import { listDefaultProps } from "./defaultProps";
|
|
14
|
+
import { useListVirtualScroll } from "./hooks/useListVirtualScroll";
|
|
15
|
+
|
|
16
|
+
import type { StyledProps } from "../common";
|
|
17
|
+
import type { ListInstanceFunctions, TdListProps } from "./type";
|
|
18
|
+
|
|
19
|
+
export interface ListProps extends TdListProps, StyledProps {
|
|
20
|
+
/**
|
|
21
|
+
* 文本内容
|
|
22
|
+
*/
|
|
23
|
+
children?: React.ReactNode;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 列表组件
|
|
28
|
+
*/
|
|
29
|
+
const List = forwardRefWithStatics(
|
|
30
|
+
(props: ListProps, ref: React.Ref<ListInstanceFunctions>) => {
|
|
31
|
+
const {
|
|
32
|
+
header,
|
|
33
|
+
footer,
|
|
34
|
+
asyncLoading,
|
|
35
|
+
size,
|
|
36
|
+
split,
|
|
37
|
+
stripe,
|
|
38
|
+
layout,
|
|
39
|
+
children,
|
|
40
|
+
className,
|
|
41
|
+
onLoadMore = noop,
|
|
42
|
+
onScroll = noop,
|
|
43
|
+
style,
|
|
44
|
+
scroll
|
|
45
|
+
} = useDefaultProps<ListProps>(props, listDefaultProps);
|
|
46
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
47
|
+
|
|
48
|
+
const { classPrefix } = useConfig();
|
|
49
|
+
const [local, t] = useLocaleReceiver("list");
|
|
50
|
+
|
|
51
|
+
const listItems = useMemo(
|
|
52
|
+
() => compact(React.Children.map(children, (child: React.ReactElement) => child?.props)) ?? [],
|
|
53
|
+
[children]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const { virtualConfig, cursorStyle, listStyle, isVirtualScroll, onInnerVirtualScroll, scrollToElement } =
|
|
57
|
+
useListVirtualScroll(scroll, wrapperRef, listItems);
|
|
58
|
+
|
|
59
|
+
const COMPONENT_NAME = `${classPrefix}-list`;
|
|
60
|
+
|
|
61
|
+
const handleClickLoad = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
62
|
+
if (asyncLoading === "load-more") {
|
|
63
|
+
onLoadMore({ e });
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleScroll = (event: WheelEvent<HTMLDivElement>): void => {
|
|
68
|
+
const { currentTarget } = event;
|
|
69
|
+
const { scrollTop, offsetHeight, scrollHeight } = currentTarget;
|
|
70
|
+
const scrollBottom = scrollHeight - scrollTop - offsetHeight;
|
|
71
|
+
if (isVirtualScroll) onInnerVirtualScroll(event as unknown as globalThis.WheelEvent);
|
|
72
|
+
onScroll({ e: event, scrollTop, scrollBottom });
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const loadElement = isString(asyncLoading) ? (
|
|
76
|
+
<div
|
|
77
|
+
className={classNames(`${classPrefix}-list__load`, {
|
|
78
|
+
[`${classPrefix}-list__load--loading`]: asyncLoading === "loading",
|
|
79
|
+
[`${classPrefix}-list__load--load-more`]: asyncLoading === "load-more"
|
|
80
|
+
})}
|
|
81
|
+
onClick={handleClickLoad}
|
|
82
|
+
>
|
|
83
|
+
{asyncLoading === "loading" && (
|
|
84
|
+
<div>
|
|
85
|
+
<Loading loading={true} />
|
|
86
|
+
<span>{t(local.loadingText)}</span>
|
|
87
|
+
</div>
|
|
88
|
+
)}
|
|
89
|
+
{asyncLoading === "load-more" && <span>{t(local.loadingMoreText)}</span>}
|
|
90
|
+
</div>
|
|
91
|
+
) : (
|
|
92
|
+
asyncLoading
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
useImperativeHandle(ref, () => ({
|
|
96
|
+
scrollTo: scrollToElement
|
|
97
|
+
}));
|
|
98
|
+
|
|
99
|
+
const renderContent = () => (
|
|
100
|
+
<>
|
|
101
|
+
{isVirtualScroll ? (
|
|
102
|
+
<>
|
|
103
|
+
<div style={cursorStyle}></div>
|
|
104
|
+
<ul className={`${COMPONENT_NAME}__inner`} style={listStyle}>
|
|
105
|
+
{virtualConfig.visibleData.map((item, index) => (
|
|
106
|
+
<ListItem key={index} {...(item as any)} />
|
|
107
|
+
))}
|
|
108
|
+
</ul>
|
|
109
|
+
</>
|
|
110
|
+
) : (
|
|
111
|
+
<ul className={`${COMPONENT_NAME}__inner`}>{children}</ul>
|
|
112
|
+
)}
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<div
|
|
118
|
+
ref={wrapperRef}
|
|
119
|
+
style={{
|
|
120
|
+
...style,
|
|
121
|
+
position: isVirtualScroll ? "relative" : undefined
|
|
122
|
+
}}
|
|
123
|
+
onScroll={handleScroll}
|
|
124
|
+
className={classNames(`${COMPONENT_NAME}`, className, {
|
|
125
|
+
[`${COMPONENT_NAME}--split`]: split,
|
|
126
|
+
[`${COMPONENT_NAME}--stripe`]: stripe,
|
|
127
|
+
[`${COMPONENT_NAME}--vertical-action`]: layout === "vertical",
|
|
128
|
+
[`${classPrefix}-size-s`]: size === "small",
|
|
129
|
+
[`${classPrefix}-size-l`]: size === "large"
|
|
130
|
+
})}
|
|
131
|
+
>
|
|
132
|
+
{header && <div className={`${COMPONENT_NAME}__header`}>{parseTNode(header)}</div>}
|
|
133
|
+
{renderContent()}
|
|
134
|
+
{asyncLoading && loadElement}
|
|
135
|
+
{footer && <div className={`${COMPONENT_NAME}__footer`}>{parseTNode(footer)}</div>}
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
{ ListItem, ListItemMeta }
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
List.displayName = "List";
|
|
143
|
+
|
|
144
|
+
export default List;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import useConfig from "../hooks/useConfig";
|
|
4
|
+
import { TdListItemProps } from "./type";
|
|
5
|
+
import { StyledProps } from "../common";
|
|
6
|
+
|
|
7
|
+
export interface ListItemProps extends TdListItemProps, StyledProps {
|
|
8
|
+
/**
|
|
9
|
+
* 文本内容
|
|
10
|
+
*/
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
content?: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 列表组件
|
|
17
|
+
*/
|
|
18
|
+
const ListItem = forwardRef<HTMLLIElement, ListItemProps>((props, ref) => {
|
|
19
|
+
const { children, className, style, action, content } = props;
|
|
20
|
+
const { classPrefix } = useConfig();
|
|
21
|
+
|
|
22
|
+
const actionElement = action && <ul className={`${classPrefix}-list-item__action`}>{action}</ul>;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<li ref={ref} className={classNames(`${classPrefix}-list-item`, className)} style={style}>
|
|
26
|
+
<div className={`${classPrefix}-list-item-main`}>
|
|
27
|
+
{children ? children : content}
|
|
28
|
+
{actionElement}
|
|
29
|
+
</div>
|
|
30
|
+
</li>
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
ListItem.displayName = "ListItem";
|
|
35
|
+
|
|
36
|
+
export default ListItem;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import useConfig from "../hooks/useConfig";
|
|
4
|
+
import { TdListItemMetaProps } from "./type";
|
|
5
|
+
import { StyledProps } from "../common";
|
|
6
|
+
|
|
7
|
+
export interface ListItemMetaProps extends TdListItemMetaProps, StyledProps {}
|
|
8
|
+
/**
|
|
9
|
+
* 列表组件
|
|
10
|
+
*/
|
|
11
|
+
const ListItemMeta = forwardRef<HTMLDivElement, ListItemMetaProps>((props, ref) => {
|
|
12
|
+
const { title, image, description, className, style } = props;
|
|
13
|
+
const { classPrefix } = useConfig();
|
|
14
|
+
|
|
15
|
+
const renderAvatar = () => {
|
|
16
|
+
if (image && typeof image === "string") {
|
|
17
|
+
return (
|
|
18
|
+
<div className={`${classPrefix}-list-item__meta-avatar`}>
|
|
19
|
+
<img src={image} alt="" />
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
return <div className={`${classPrefix}-list-item__meta-avatar`}>{image}</div>;
|
|
24
|
+
};
|
|
25
|
+
return (
|
|
26
|
+
<div ref={ref} className={classNames(`${classPrefix}-list-item__meta`, className)} style={style}>
|
|
27
|
+
{image && renderAvatar()}
|
|
28
|
+
<div className={`${classPrefix}-list-item__meta-content`}>
|
|
29
|
+
<h3 className={`${classPrefix}-list-item__meta-title`}>{title}</h3>
|
|
30
|
+
<div className={`${classPrefix}-list-item__meta-description`}>
|
|
31
|
+
{typeof description === "string" ? <p>{description}</p> : description}
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
ListItemMeta.displayName = "ListItemMeta";
|
|
39
|
+
|
|
40
|
+
export default ListItemMeta;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
|
3
|
+
* */
|
|
4
|
+
|
|
5
|
+
import { TdListProps, TdListItemProps, TdListItemMetaProps } from "./type";
|
|
6
|
+
|
|
7
|
+
export const listDefaultProps: TdListProps = { layout: "horizontal", size: "medium", split: false, stripe: false };
|
|
8
|
+
|
|
9
|
+
export const listItemDefaultProps: TdListItemProps = {};
|
|
10
|
+
|
|
11
|
+
export const listItemMetaDefaultProps: TdListItemMetaProps = {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
// import log from "@tdesign/common-js/log/index";
|
|
3
|
+
import useVirtualScroll from "../../hooks/useVirtualScroll";
|
|
4
|
+
import { TdListProps } from "../type";
|
|
5
|
+
import { Styles, type ScrollToElementParams } from "../../common";
|
|
6
|
+
const log = console.log;
|
|
7
|
+
export const useListVirtualScroll = (
|
|
8
|
+
scroll: TdListProps["scroll"],
|
|
9
|
+
listRef: React.MutableRefObject<HTMLElement>,
|
|
10
|
+
listItems: any[]
|
|
11
|
+
) => {
|
|
12
|
+
const virtualScrollParams = useMemo(
|
|
13
|
+
() => ({
|
|
14
|
+
data: listItems,
|
|
15
|
+
scroll
|
|
16
|
+
}),
|
|
17
|
+
[listItems, scroll]
|
|
18
|
+
);
|
|
19
|
+
const virtualConfig = useVirtualScroll(listRef, virtualScrollParams);
|
|
20
|
+
const { isVirtualScroll } = virtualConfig;
|
|
21
|
+
let lastScrollY = -1;
|
|
22
|
+
|
|
23
|
+
const onInnerVirtualScroll = (e: WheelEvent) => {
|
|
24
|
+
const target = (e.target || e.srcElement) as HTMLElement;
|
|
25
|
+
const top = target.scrollTop;
|
|
26
|
+
if (lastScrollY !== top) {
|
|
27
|
+
virtualConfig.isVirtualScroll && virtualConfig.handleScroll();
|
|
28
|
+
} else {
|
|
29
|
+
lastScrollY = -1;
|
|
30
|
+
}
|
|
31
|
+
lastScrollY = top;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const cursorStyle = useMemo(
|
|
35
|
+
() =>
|
|
36
|
+
({
|
|
37
|
+
position: "absolute",
|
|
38
|
+
width: "1px",
|
|
39
|
+
height: "1px",
|
|
40
|
+
transition: "transform 0.2s",
|
|
41
|
+
transform: `translate(0, ${virtualConfig.scrollHeight}px)`,
|
|
42
|
+
msTransform: `translate(0, ${virtualConfig.scrollHeight}px)`,
|
|
43
|
+
MozTransform: `translate(0, ${virtualConfig.scrollHeight}px)`,
|
|
44
|
+
WebkitTransform: `translate(0, ${virtualConfig.scrollHeight}px)`
|
|
45
|
+
}) as Styles,
|
|
46
|
+
[virtualConfig.scrollHeight]
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const listStyle = useMemo(
|
|
50
|
+
() =>
|
|
51
|
+
({
|
|
52
|
+
transform: `translate(0, ${virtualConfig.translateY}px)`,
|
|
53
|
+
msTransform: `translate(0, ${virtualConfig.translateY}px)`,
|
|
54
|
+
MozTransform: `translate(0, ${virtualConfig.translateY}px)`,
|
|
55
|
+
WebkitTransform: `translate(0, ${virtualConfig.translateY}px)`
|
|
56
|
+
}) as Styles,
|
|
57
|
+
[virtualConfig.translateY]
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const handleScrollTo = (params: ScrollToElementParams) => {
|
|
61
|
+
const { index, key } = params;
|
|
62
|
+
const targetIndex = index === 0 ? index : index ?? Number(key);
|
|
63
|
+
if (!targetIndex && targetIndex !== 0) {
|
|
64
|
+
console.error("List", "scrollTo: `index` or `key` must exist.");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (targetIndex < 0 || targetIndex >= listItems.length) {
|
|
68
|
+
console.error("List", `${targetIndex} does not exist in data, check \`index\` or \`key\` please.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
virtualConfig.scrollToElement({ ...params, index: targetIndex - 1 });
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
virtualConfig,
|
|
76
|
+
cursorStyle,
|
|
77
|
+
listStyle,
|
|
78
|
+
isVirtualScroll,
|
|
79
|
+
onInnerVirtualScroll,
|
|
80
|
+
scrollToElement: handleScrollTo
|
|
81
|
+
};
|
|
82
|
+
};
|
package/list/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import _List from "./List";
|
|
2
|
+
|
|
3
|
+
import "./style/index.js";
|
|
4
|
+
|
|
5
|
+
export type { ListProps } from "./List";
|
|
6
|
+
export type { ListItemProps } from "./ListItem";
|
|
7
|
+
export type { ListItemMetaProps } from "./ListItemMeta";
|
|
8
|
+
export * from "./type";
|
|
9
|
+
|
|
10
|
+
export const List = _List;
|
|
11
|
+
export default List;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./index.css";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../../styles/components/list/_index.scss";
|