@wzyjs/components 0.2.56 → 0.2.57
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/package.json +2 -2
- package/src/DynamicSelect/index.tsx +77 -0
- package/src/DynamicSelect/utils.ts +47 -0
- package/src/JsonRenderer/index.tsx +115 -0
- package/src/Markdown/index.tsx +1 -1
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wzyjs/components",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.57",
|
|
4
4
|
"description": "description",
|
|
5
5
|
"author": "wzy",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@types/react-grid-layout": "^1.3.5",
|
|
44
44
|
"@types/react-syntax-highlighter": "^15.5.5"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "7603b720b28050ff484e841ae23e60a330db8956",
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
49
49
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { AutoComplete, Button, Space } from 'app/src/components'
|
|
3
|
+
import { type Option } from 'app/src/types'
|
|
4
|
+
|
|
5
|
+
export * from './utils'
|
|
6
|
+
|
|
7
|
+
interface DynamicSelectProps {
|
|
8
|
+
value?: string[]
|
|
9
|
+
onChange?: (value: string[]) => void
|
|
10
|
+
options?: Option[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const DynamicSelect = (props: DynamicSelectProps) => {
|
|
14
|
+
const { value = [''], onChange, options = [] } = props
|
|
15
|
+
|
|
16
|
+
const removeOption = (index: number) => {
|
|
17
|
+
const newOptions = [...value]
|
|
18
|
+
newOptions.splice(index, 1)
|
|
19
|
+
onChange?.(newOptions)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const handleChange = (index: number, val: string) => {
|
|
23
|
+
const newValue = [...[...value].slice(0, index), val]
|
|
24
|
+
onChange?.(newValue)
|
|
25
|
+
|
|
26
|
+
if (newValue.every(item => item)) {
|
|
27
|
+
onChange?.([...newValue, ''])
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const getOptions = (options: Option[], index: number): Option[] => {
|
|
32
|
+
if (index === 0) {
|
|
33
|
+
return options
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const currentValue = value[value.length - 1 - index]
|
|
37
|
+
if (!currentValue) return []
|
|
38
|
+
|
|
39
|
+
return getOptions(
|
|
40
|
+
options.find(item => item.value === currentValue)?.children || [],
|
|
41
|
+
index - 1,
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Space size={8} align='center'>
|
|
47
|
+
{value.map((val, index) => (
|
|
48
|
+
<Space key={index} size={4} align='center'>
|
|
49
|
+
<AutoComplete
|
|
50
|
+
style={{
|
|
51
|
+
minWidth: '120px',
|
|
52
|
+
maxWidth: '300px',
|
|
53
|
+
width: 'auto',
|
|
54
|
+
}}
|
|
55
|
+
value={val}
|
|
56
|
+
onChange={val => handleChange(index, val)}
|
|
57
|
+
options={getOptions(options, index)}
|
|
58
|
+
placeholder={`请选择第 ${index + 1} 级`}
|
|
59
|
+
/>
|
|
60
|
+
{index !== 0 && (
|
|
61
|
+
<Button
|
|
62
|
+
type='text'
|
|
63
|
+
danger
|
|
64
|
+
size='small'
|
|
65
|
+
onClick={() => removeOption(index)}
|
|
66
|
+
>
|
|
67
|
+
删除
|
|
68
|
+
</Button>
|
|
69
|
+
)}
|
|
70
|
+
{index < value.length - 1 && (
|
|
71
|
+
<span style={{ color: '#999' }}>/</span>
|
|
72
|
+
)}
|
|
73
|
+
</Space>
|
|
74
|
+
))}
|
|
75
|
+
</Space>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Option } from '@wzyjs/types'
|
|
2
|
+
|
|
3
|
+
export const transformOptions = (data: string[][]): Option[] => {
|
|
4
|
+
const result: Option[] = []
|
|
5
|
+
|
|
6
|
+
data.forEach((item = []) => {
|
|
7
|
+
let currentNode: Option | undefined
|
|
8
|
+
let parentNode: Option | undefined
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < item.length; i++) {
|
|
11
|
+
const currentValue = item[i]
|
|
12
|
+
if (!currentValue) continue
|
|
13
|
+
|
|
14
|
+
if (i === 0) {
|
|
15
|
+
currentNode = result.find(r => r.value === currentValue)
|
|
16
|
+
|
|
17
|
+
if (!currentNode) {
|
|
18
|
+
currentNode = {
|
|
19
|
+
label: currentValue,
|
|
20
|
+
value: currentValue,
|
|
21
|
+
}
|
|
22
|
+
result.push(currentNode)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
parentNode = currentNode
|
|
26
|
+
} else {
|
|
27
|
+
currentNode = parentNode?.children?.find(c => c.value === currentValue)
|
|
28
|
+
|
|
29
|
+
if (!currentNode) {
|
|
30
|
+
currentNode = {
|
|
31
|
+
label: currentValue,
|
|
32
|
+
value: currentValue,
|
|
33
|
+
}
|
|
34
|
+
if (!parentNode) {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
parentNode.children = parentNode.children || []
|
|
38
|
+
parentNode.children.push(currentNode)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
parentNode = currentNode
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
return result
|
|
47
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
Divider,
|
|
4
|
+
Flex,
|
|
5
|
+
Space,
|
|
6
|
+
Typography,
|
|
7
|
+
Steps,
|
|
8
|
+
Tabs,
|
|
9
|
+
Collapse,
|
|
10
|
+
Descriptions,
|
|
11
|
+
Image,
|
|
12
|
+
List,
|
|
13
|
+
Popover,
|
|
14
|
+
Tooltip,
|
|
15
|
+
Card,
|
|
16
|
+
QRCode,
|
|
17
|
+
Segmented,
|
|
18
|
+
Table,
|
|
19
|
+
Tag,
|
|
20
|
+
Timeline,
|
|
21
|
+
Tree,
|
|
22
|
+
Alert,
|
|
23
|
+
Progress,
|
|
24
|
+
} from 'antd'
|
|
25
|
+
|
|
26
|
+
const ComponentMap = {
|
|
27
|
+
// 布局结构类
|
|
28
|
+
Divider,
|
|
29
|
+
Flex,
|
|
30
|
+
Space,
|
|
31
|
+
|
|
32
|
+
// 信息展示类
|
|
33
|
+
Typography,
|
|
34
|
+
'Typography.Title': Typography.Title,
|
|
35
|
+
'Typography.Text': Typography.Text,
|
|
36
|
+
'Typography.Paragraph': Typography.Paragraph,
|
|
37
|
+
'Typography.Link': Typography.Link,
|
|
38
|
+
Steps,
|
|
39
|
+
Tabs,
|
|
40
|
+
'Tabs.TabPane': Tabs.TabPane,
|
|
41
|
+
Collapse,
|
|
42
|
+
'Collapse.Panel': Collapse.Panel,
|
|
43
|
+
Description: Descriptions,
|
|
44
|
+
Image,
|
|
45
|
+
List,
|
|
46
|
+
Popover,
|
|
47
|
+
Tooltip,
|
|
48
|
+
Card,
|
|
49
|
+
QRCode,
|
|
50
|
+
Segmented,
|
|
51
|
+
Table,
|
|
52
|
+
Tag,
|
|
53
|
+
Timeline,
|
|
54
|
+
Tree,
|
|
55
|
+
Alert,
|
|
56
|
+
Progress,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface Content {
|
|
60
|
+
component: keyof typeof ComponentMap // 对应 Ant Design 组件的枚举值
|
|
61
|
+
props?: Record<string, any> // 对应组件的 props 配置
|
|
62
|
+
children?: Content[] | string // 子节点,可递归嵌套,或直接是字符串
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface JsonRendererProps {
|
|
66
|
+
content: Content[]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const JsonRenderer = (props: JsonRendererProps) => {
|
|
70
|
+
const { content } = props
|
|
71
|
+
|
|
72
|
+
// 递归渲染组件的函数
|
|
73
|
+
const renderContent = (item: Content | string) => {
|
|
74
|
+
// 如果是字符串,直接返回
|
|
75
|
+
if (typeof item === 'string') {
|
|
76
|
+
return item
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const { component, props = {}, children } = item
|
|
80
|
+
|
|
81
|
+
// 获取对应的组件
|
|
82
|
+
const Component = ComponentMap[component] as React.ComponentType<any>
|
|
83
|
+
|
|
84
|
+
if (!Component) {
|
|
85
|
+
return <Alert type='error' message={`未找到组件: ${component}`} />
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 处理子节点
|
|
89
|
+
let childrenContent
|
|
90
|
+
if (children) {
|
|
91
|
+
if (Array.isArray(children)) {
|
|
92
|
+
childrenContent = children.map((child, index) => (
|
|
93
|
+
<React.Fragment key={index}>
|
|
94
|
+
{renderContent(child)}
|
|
95
|
+
</React.Fragment>
|
|
96
|
+
))
|
|
97
|
+
} else {
|
|
98
|
+
childrenContent = renderContent(children)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 渲染组件,传递 props 和 children
|
|
103
|
+
return <Component {...props}>{childrenContent}</Component>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<>
|
|
108
|
+
{content.map((item, index) => (
|
|
109
|
+
<React.Fragment key={index}>
|
|
110
|
+
{renderContent(item)}
|
|
111
|
+
</React.Fragment>
|
|
112
|
+
))}
|
|
113
|
+
</>
|
|
114
|
+
)
|
|
115
|
+
}
|
package/src/Markdown/index.tsx
CHANGED
package/src/index.ts
CHANGED