@easy-editor/materials-dashboard-scroll-list 0.0.2 → 0.0.4
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/CHANGELOG.md +14 -0
- package/dist/component.min.js +1 -2
- package/dist/index.min.js +1 -2
- package/dist/meta.min.js +1 -2
- package/easypack.config.ts +10 -0
- package/package.json +4 -8
- package/src/component.tsx +219 -189
- package/src/configure.ts +189 -439
- package/src/index.tsx +7 -7
- package/src/meta.ts +26 -28
- package/src/snippets.ts +76 -64
- package/tsconfig.json +20 -9
- package/.vite/plugins/vite-plugin-external-deps.ts +0 -224
- package/.vite/plugins/vite-plugin-material-dev.ts +0 -218
- package/dist/component.esm.js +0 -176
- package/dist/component.esm.js.map +0 -1
- package/dist/component.js +0 -185
- package/dist/component.js.map +0 -1
- package/dist/component.min.js.map +0 -1
- package/dist/index.cjs +0 -669
- package/dist/index.cjs.map +0 -1
- package/dist/index.esm.js +0 -666
- package/dist/index.esm.js.map +0 -1
- package/dist/index.js +0 -674
- package/dist/index.js.map +0 -1
- package/dist/index.min.js.map +0 -1
- package/dist/meta.esm.js +0 -494
- package/dist/meta.esm.js.map +0 -1
- package/dist/meta.js +0 -505
- package/dist/meta.js.map +0 -1
- package/dist/meta.min.js.map +0 -1
- package/dist/src/component.d.ts +0 -51
- package/dist/src/configure.d.ts +0 -7
- package/dist/src/constants.d.ts +0 -16
- package/dist/src/index.d.ts +0 -6
- package/dist/src/meta.d.ts +0 -7
- package/dist/src/snippets.d.ts +0 -7
- package/rollup.config.js +0 -222
- package/tsconfig.build.json +0 -12
- package/tsconfig.test.json +0 -7
- package/vite.config.ts +0 -54
package/src/component.tsx
CHANGED
|
@@ -1,189 +1,219 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Scroll List Component
|
|
3
|
-
* 滚动列表组件 -
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import { cn } from '@easy-editor/materials-shared'
|
|
8
|
-
import styles from './component.module.css'
|
|
9
|
-
|
|
10
|
-
export interface ScrollListItem {
|
|
11
|
-
rank: number
|
|
12
|
-
name: string
|
|
13
|
-
value: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ScrollListProps {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Scroll List Component
|
|
3
|
+
* 滚动列表组件 - 支持数据源绑定和事件交互
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useMemo, type CSSProperties } from 'react'
|
|
7
|
+
import { cn, useDataSource, type MaterialComponet } from '@easy-editor/materials-shared'
|
|
8
|
+
import styles from './component.module.css'
|
|
9
|
+
|
|
10
|
+
export interface ScrollListItem {
|
|
11
|
+
rank: number
|
|
12
|
+
name: string
|
|
13
|
+
value: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ScrollListProps extends MaterialComponet {
|
|
17
|
+
/** 最大显示条数 */
|
|
18
|
+
maxItems?: number
|
|
19
|
+
/** 是否显示排名 */
|
|
20
|
+
showRank?: boolean
|
|
21
|
+
/** 是否显示奖牌图标 */
|
|
22
|
+
showMedal?: boolean
|
|
23
|
+
/** 是否显示进度条 */
|
|
24
|
+
progressBarEnable?: boolean
|
|
25
|
+
/** 是否使用渐变进度条 */
|
|
26
|
+
progressBarGradient?: boolean
|
|
27
|
+
/** 进度条颜色 [起始色, 结束色] */
|
|
28
|
+
progressBarColors?: [string, string]
|
|
29
|
+
/** 数值格式化 */
|
|
30
|
+
valueFormat?: 'number' | 'currency' | 'percent'
|
|
31
|
+
/** 数值前缀 */
|
|
32
|
+
valuePrefix?: string
|
|
33
|
+
/** 数值后缀 */
|
|
34
|
+
valueSuffix?: string
|
|
35
|
+
/** 名称颜色 */
|
|
36
|
+
nameColor?: string
|
|
37
|
+
/** 数值颜色 */
|
|
38
|
+
valueColor?: string
|
|
39
|
+
/** 背景颜色 */
|
|
40
|
+
backgroundColor?: string
|
|
41
|
+
/** 边框颜色 */
|
|
42
|
+
borderColor?: string
|
|
43
|
+
/** 行背景颜色 */
|
|
44
|
+
itemBackgroundColor?: string
|
|
45
|
+
/** 行边框颜色 */
|
|
46
|
+
itemBorderColor?: string
|
|
47
|
+
/** 是否显示发光效果 */
|
|
48
|
+
glowEnable?: boolean
|
|
49
|
+
/** 点击事件 */
|
|
50
|
+
onClick?: (e: React.MouseEvent) => void
|
|
51
|
+
/** 双击事件 */
|
|
52
|
+
onDoubleClick?: (e: React.MouseEvent) => void
|
|
53
|
+
/** 鼠标进入 */
|
|
54
|
+
onMouseEnter?: (e: React.MouseEvent) => void
|
|
55
|
+
/** 鼠标离开 */
|
|
56
|
+
onMouseLeave?: (e: React.MouseEvent) => void
|
|
57
|
+
/** 行点击事件 */
|
|
58
|
+
onItemClick?: (item: ScrollListItem, index: number) => void
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const DEFAULT_DATA: ScrollListItem[] = [
|
|
62
|
+
{ rank: 1, name: '北京市', value: 9800 },
|
|
63
|
+
{ rank: 2, name: '上海市', value: 8500 },
|
|
64
|
+
{ rank: 3, name: '广州市', value: 7200 },
|
|
65
|
+
{ rank: 4, name: '深圳市', value: 6100 },
|
|
66
|
+
{ rank: 5, name: '杭州市', value: 4800 },
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
const MEDAL_EMOJI: Record<number, string> = {
|
|
70
|
+
1: '🥇',
|
|
71
|
+
2: '🥈',
|
|
72
|
+
3: '🥉',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const getRankClass = (rank: number): string => {
|
|
76
|
+
if (rank === 1) {
|
|
77
|
+
return styles.rankGold
|
|
78
|
+
}
|
|
79
|
+
if (rank === 2) {
|
|
80
|
+
return styles.rankSilver
|
|
81
|
+
}
|
|
82
|
+
if (rank === 3) {
|
|
83
|
+
return styles.rankBronze
|
|
84
|
+
}
|
|
85
|
+
return ''
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const formatDisplayValue = (value: number, format: string, prefix: string, suffix: string): string => {
|
|
89
|
+
let formatted: string
|
|
90
|
+
switch (format) {
|
|
91
|
+
case 'currency':
|
|
92
|
+
formatted = value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
93
|
+
break
|
|
94
|
+
case 'percent':
|
|
95
|
+
formatted = `${value}%`
|
|
96
|
+
break
|
|
97
|
+
default:
|
|
98
|
+
formatted = value.toLocaleString()
|
|
99
|
+
}
|
|
100
|
+
return `${prefix}${formatted}${suffix}`
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const ScrollList: React.FC<ScrollListProps> = ({
|
|
104
|
+
ref,
|
|
105
|
+
$data,
|
|
106
|
+
__dataSource,
|
|
107
|
+
maxItems = 5,
|
|
108
|
+
showRank = true,
|
|
109
|
+
showMedal = true,
|
|
110
|
+
progressBarEnable = true,
|
|
111
|
+
progressBarGradient = true,
|
|
112
|
+
progressBarColors = ['#00d4ff', '#9b59b6'],
|
|
113
|
+
valueFormat = 'number',
|
|
114
|
+
valuePrefix = '',
|
|
115
|
+
valueSuffix = '',
|
|
116
|
+
nameColor = '#e6e6e6',
|
|
117
|
+
valueColor = '#00d4ff',
|
|
118
|
+
backgroundColor = 'rgba(10, 10, 26, 0.95)',
|
|
119
|
+
borderColor = 'rgba(26, 26, 62, 0.8)',
|
|
120
|
+
itemBackgroundColor = 'rgba(15, 15, 42, 0.9)',
|
|
121
|
+
itemBorderColor = 'rgba(26, 26, 62, 0.6)',
|
|
122
|
+
glowEnable = false,
|
|
123
|
+
rotation = 0,
|
|
124
|
+
opacity = 100,
|
|
125
|
+
style: externalStyle,
|
|
126
|
+
onClick,
|
|
127
|
+
onDoubleClick,
|
|
128
|
+
onMouseEnter,
|
|
129
|
+
onMouseLeave,
|
|
130
|
+
onItemClick,
|
|
131
|
+
}) => {
|
|
132
|
+
// 解析数据源
|
|
133
|
+
const dataSource = useDataSource($data, __dataSource)
|
|
134
|
+
const data = useMemo<ScrollListItem[]>(() => {
|
|
135
|
+
if (dataSource.length > 0) {
|
|
136
|
+
return dataSource as ScrollListItem[]
|
|
137
|
+
}
|
|
138
|
+
return DEFAULT_DATA
|
|
139
|
+
}, [dataSource])
|
|
140
|
+
|
|
141
|
+
const displayData = data.slice(0, maxItems)
|
|
142
|
+
const maxValue = Math.max(...displayData.map(item => item.value), 1)
|
|
143
|
+
|
|
144
|
+
const getProgressBarStyle = (value: number): CSSProperties => {
|
|
145
|
+
const percentage = (value / maxValue) * 100
|
|
146
|
+
return {
|
|
147
|
+
width: `${percentage}%`,
|
|
148
|
+
background: progressBarGradient
|
|
149
|
+
? `linear-gradient(90deg, ${progressBarColors[0]}, ${progressBarColors[1]})`
|
|
150
|
+
: progressBarColors[0],
|
|
151
|
+
boxShadow: glowEnable ? `0 0 8px ${progressBarColors[0]}60` : undefined,
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const containerStyle: CSSProperties = {
|
|
156
|
+
transform: rotation !== 0 ? `rotate(${rotation}deg)` : undefined,
|
|
157
|
+
opacity: opacity / 100,
|
|
158
|
+
backgroundColor,
|
|
159
|
+
borderColor,
|
|
160
|
+
...externalStyle,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const itemStyle: CSSProperties = {
|
|
164
|
+
backgroundColor: itemBackgroundColor,
|
|
165
|
+
borderColor: itemBorderColor,
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<div
|
|
170
|
+
className={styles.container}
|
|
171
|
+
onClick={onClick}
|
|
172
|
+
onDoubleClick={onDoubleClick}
|
|
173
|
+
onMouseEnter={onMouseEnter}
|
|
174
|
+
onMouseLeave={onMouseLeave}
|
|
175
|
+
ref={ref}
|
|
176
|
+
style={containerStyle}
|
|
177
|
+
>
|
|
178
|
+
<div className={styles.list}>
|
|
179
|
+
{displayData.map((item, index) => {
|
|
180
|
+
const isTopThree = item.rank <= 3
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div className={styles.item} key={item.rank} onClick={() => onItemClick?.(item, index)} style={itemStyle}>
|
|
184
|
+
{/* Rank Badge */}
|
|
185
|
+
{showRank ? (
|
|
186
|
+
<div
|
|
187
|
+
className={cn(
|
|
188
|
+
styles.rankBadge,
|
|
189
|
+
isTopThree ? styles.rankBadgeTopThree : styles.rankBadgeNormal,
|
|
190
|
+
getRankClass(item.rank),
|
|
191
|
+
)}
|
|
192
|
+
>
|
|
193
|
+
{showMedal && isTopThree ? MEDAL_EMOJI[item.rank] : item.rank}
|
|
194
|
+
</div>
|
|
195
|
+
) : null}
|
|
196
|
+
|
|
197
|
+
{/* Name */}
|
|
198
|
+
<div className={styles.name} style={{ color: nameColor }}>
|
|
199
|
+
{item.name}
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
{/* Value and Progress */}
|
|
203
|
+
<div className={styles.valueContainer}>
|
|
204
|
+
<span className={styles.value} style={{ color: valueColor }}>
|
|
205
|
+
{formatDisplayValue(item.value, valueFormat, valuePrefix, valueSuffix)}
|
|
206
|
+
</span>
|
|
207
|
+
{progressBarEnable ? (
|
|
208
|
+
<div className={styles.progressBar}>
|
|
209
|
+
<div className={styles.progressFill} style={getProgressBarStyle(item.value)} />
|
|
210
|
+
</div>
|
|
211
|
+
) : null}
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
)
|
|
215
|
+
})}
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
)
|
|
219
|
+
}
|