weimo-ui-stats 0.0.0-stage → 0.1.0
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/README.md +174 -2
- package/dist/components/heatmap/heat-color.css +58 -0
- package/dist/components/heatmap/heat-color.d.css.ts +1 -0
- package/dist/components/heatmap/heat-color.d.ts +65 -0
- package/dist/components/heatmap/heat-color.d.ts.map +1 -0
- package/dist/components/heatmap/heat-color.js +73 -0
- package/dist/components/heatmap/heat-color.js.map +1 -0
- package/dist/components/heatmap/heatmap-model.d.ts +26 -0
- package/dist/components/heatmap/heatmap-model.d.ts.map +1 -0
- package/dist/components/heatmap/heatmap-model.js +82 -0
- package/dist/components/heatmap/heatmap-model.js.map +1 -0
- package/dist/components/heatmap/heatmap.css +100 -0
- package/dist/components/heatmap/heatmap.d.css.ts +1 -0
- package/dist/components/heatmap/heatmap.d.ts +13 -0
- package/dist/components/heatmap/heatmap.d.ts.map +1 -0
- package/dist/components/heatmap/heatmap.js +30 -0
- package/dist/components/heatmap/heatmap.js.map +1 -0
- package/dist/components/heatmap/index.d.ts +3 -0
- package/dist/components/heatmap/index.d.ts.map +1 -0
- package/dist/components/heatmap/index.js +3 -0
- package/dist/components/heatmap/index.js.map +1 -0
- package/dist/components/stat-group/stat-group.css +35 -0
- package/dist/components/stat-group/stat-group.d.css.ts +1 -0
- package/dist/components/stat-group/stat-group.d.ts +12 -0
- package/dist/components/stat-group/stat-group.d.ts.map +1 -0
- package/dist/components/stat-group/stat-group.js +7 -0
- package/dist/components/stat-group/stat-group.js.map +1 -0
- package/package.json +79 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 jiaowenjun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,175 @@
|
|
|
1
|
-
#
|
|
1
|
+
# weimo-ui-stats
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 你的坚持,看得见 —— 为笔记与打卡而生。
|
|
4
|
+
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://react.dev)
|
|
7
|
+
[](https://jiaowenjun.github.io/weimo-ui-stats/)
|
|
8
|
+
|
|
9
|
+
**[🚀 打开在线演示,亲手点点看 →](https://jiaowenjun.github.io/weimo-ui-stats/)**
|
|
10
|
+
|
|
11
|
+
如果你在做笔记应用、写作工具、习惯打卡,需要一块像 GitHub 贡献图那样「一眼看出最近写了多少」的概览区,`weimo-ui-stats` 就是为你准备的:
|
|
12
|
+
|
|
13
|
+
- **`Heatmap` 日期热力图** —— 把「日期 → 条数」渲染成按周排列的 13 周活动方格,带月份标签、今日环、选中态与悬浮提示;
|
|
14
|
+
- **`HeatColor` 热力色阶** —— 热力图的 5 级背景色阶,既是展示用的色卡组件,也是 `--color-heat-0..4` token 的归属地;
|
|
15
|
+
- **`StatGroup` 统计组** —— 把「128 篇笔记 / 1.2 万字 / 36 天」这样的指标横排成一组大数字小标签。
|
|
16
|
+
|
|
17
|
+
组件基于 React 19 构建,视觉语言(主题 token、悬浮提示)来自 [weimo-ui-core](https://github.com/jiaowenjun/weimo-ui-core) 设计系统,深浅色主题自动适配。
|
|
18
|
+
|
|
19
|
+
## ✨ 特性
|
|
20
|
+
|
|
21
|
+
- **固定视窗,稳定布局** —— 热力图始终展示截至本周的 13 个 ISO 周(周一起始),不随数据多少抖动
|
|
22
|
+
- **自动分级** —— 按条数映射 0–4 级热力:无记录 / 1 条 / 2–3 条 / 4–5 条 / 6 条及以上
|
|
23
|
+
- **今日与选中双态** —— 今日单元格带内描边环,`activeDate` 对应的单元格带外描边,两者可叠加
|
|
24
|
+
- **悬浮提示 + 键盘可达** —— 每个单元格是原生按钮,附带 `aria-label` 与 Tooltip,聚焦态有清晰 outline
|
|
25
|
+
- **headless 模型可单独使用** —— 单元格、列、月份标签的构建函数全部导出,可脱离组件自行渲染
|
|
26
|
+
- **按需引入** —— 显式子路径导出、tree-shaking 友好,组件结构样式随导入自动加载,只需在应用入口引入一次主题 token
|
|
27
|
+
|
|
28
|
+
## 📦 安装
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm add weimo-ui-stats weimo-ui-core @base-ui/react react react-dom
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- `weimo-ui-stats@0.1.x` 搭配 `weimo-ui-core@0.1.x` 使用;`Heatmap` 的悬浮提示来自 core 的 Tooltip,因此需要 core 的对等依赖 `@base-ui/react`。
|
|
35
|
+
- 包根不提供 `.` 导出,所有组件通过显式子路径引入。
|
|
36
|
+
|
|
37
|
+
在应用入口加载一次主题 token(组件自身的结构样式与热力色 token 会随导入自动加载,无需手动引入):
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import 'weimo-ui-core/styles/tokens.css'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 🚀 快速上手
|
|
44
|
+
|
|
45
|
+
### 渲染日期热力图
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { useState } from 'react'
|
|
49
|
+
import { Heatmap, type HeatmapDailyCount } from 'weimo-ui-stats/components/heatmap'
|
|
50
|
+
|
|
51
|
+
const dailyCounts: HeatmapDailyCount[] = [
|
|
52
|
+
{ date: '2026-10-20', count: 2 },
|
|
53
|
+
{ date: '2026-10-22', count: 6 },
|
|
54
|
+
{ date: '2026-10-24', count: 1 },
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
export function ActivityOverview() {
|
|
58
|
+
const [activeDate, setActiveDate] = useState('2026-10-22')
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<Heatmap
|
|
62
|
+
activeDate={activeDate}
|
|
63
|
+
dailyCounts={dailyCounts}
|
|
64
|
+
onDateSelect={(date) => setActiveDate(date)}
|
|
65
|
+
/>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 渲染统计组
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { StatGroup } from 'weimo-ui-stats/components/stat-group'
|
|
74
|
+
|
|
75
|
+
<StatGroup
|
|
76
|
+
aria-label="笔记统计"
|
|
77
|
+
items={[
|
|
78
|
+
{ key: 'notes', value: '128', label: '笔记' },
|
|
79
|
+
{ key: 'words', value: '1.2', label: '万字' },
|
|
80
|
+
{ key: 'days', value: '36', label: '天' },
|
|
81
|
+
]}
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 展示热力色阶
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { HeatColor } from 'weimo-ui-stats/components/heat-color'
|
|
89
|
+
|
|
90
|
+
// 默认展示 0–4 全部 5 级;也可以只传需要的级别
|
|
91
|
+
<HeatColor levels={[1, 2, 3, 4]} />
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 📖 组件 API
|
|
95
|
+
|
|
96
|
+
### `<Heatmap />`
|
|
97
|
+
|
|
98
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
99
|
+
| --- | --- | --- | --- |
|
|
100
|
+
| `dailyCounts` | `HeatmapDailyCount[]` | `[]` | 日期活动数据,`{ date: 'YYYY-MM-DD', count }`;负数按 0 处理 |
|
|
101
|
+
| `activeDate` | `string` | `''` | 当前选中的日期键,对应单元格带外描边 |
|
|
102
|
+
| `onDateSelect` | `(date: string, cell: HeatmapCell) => void` | — | 点击单元格时回调 |
|
|
103
|
+
| `ariaLabel` | `string` | `'日期热力图'` | 容器的无障碍名称(替代原生 `aria-label`) |
|
|
104
|
+
|
|
105
|
+
其余原生 `div` 属性(`className`、`role` 等)均可透传;`role` 缺省为 `group`。今日日期由组件内部按本地时间计算,不接受外部传入。
|
|
106
|
+
|
|
107
|
+
`components/heatmap` 入口同时导出 headless 模型:
|
|
108
|
+
|
|
109
|
+
| 导出 | 说明 |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `formatHeatmapDateKey(date)` | 把 `Date` 格式化为 `YYYY-MM-DD` 本地日期键 |
|
|
112
|
+
| `getHeatmapLevel(count)` | 条数 → `0 \| 1 \| 2 \| 3 \| 4` 热力级别 |
|
|
113
|
+
| `buildHeatmapCells(dailyCounts, today?, activeDate?)` | 生成 91 个按日排序的 `HeatmapCell` |
|
|
114
|
+
| `buildHeatmapColumns(cells)` | 按 7 天一列切分为 13 个 `HeatmapColumn` |
|
|
115
|
+
| `buildHeatmapMonthLabels(cells)` | 找出每月 1 日所在列,生成 `HeatmapMonthLabel` |
|
|
116
|
+
| `HeatmapCell` / `HeatmapColumn` / `HeatmapDailyCount` / `HeatmapLevel` / `HeatmapMonthLabel` | 对应类型 |
|
|
117
|
+
|
|
118
|
+
### `<HeatColor />`
|
|
119
|
+
|
|
120
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
121
|
+
| --- | --- | --- | --- |
|
|
122
|
+
| `levels` | `HeatColorLevel[]` | `[0, 1, 2, 3, 4]` | 要展示的色阶级别 |
|
|
123
|
+
| `getLevelLabel` | `(level) => string` | 内置中文文案 | 每个色块的无障碍名称 |
|
|
124
|
+
| `ariaLabel` | `string` | `'热力图颜色色阶'` | 容器的无障碍名称(替代原生 `aria-label`) |
|
|
125
|
+
|
|
126
|
+
`components/heat-color` 入口同时导出色阶元数据:
|
|
127
|
+
|
|
128
|
+
| 导出 | 说明 |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| `heatColorMap` | 每级的 `label`、`token`、亮/暗 `value`、`className`、`description` |
|
|
131
|
+
| `heatColorLevels` | `[0, 1, 2, 3, 4]` |
|
|
132
|
+
| `getHeatColorClassName(level)` | 取对应的 `heat-color--N` 工具类名 |
|
|
133
|
+
| `getHeatColorToken(level)` | 取对应的 `--color-heat-N` token 名 |
|
|
134
|
+
|
|
135
|
+
### `<StatGroup />`
|
|
136
|
+
|
|
137
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
138
|
+
| --- | --- | --- | --- |
|
|
139
|
+
| `items` | `StatGroupItem[]` | `[]` | 指标列表,`{ key?, value, label }`,`value` 与 `label` 均可为任意 `ReactNode` |
|
|
140
|
+
| `children` | `ReactNode` | — | 追加在指标之后的自定义内容 |
|
|
141
|
+
|
|
142
|
+
其余原生 `div` 属性均可透传;`role` 缺省为 `group`。
|
|
143
|
+
|
|
144
|
+
### 样式入口
|
|
145
|
+
|
|
146
|
+
组件会随导入自动加载各自的样式;若需单独引入(例如在非 React 场景复用 token),可使用:
|
|
147
|
+
|
|
148
|
+
| 入口 | 内容 |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `styles/heat-color.css` | `--color-heat-0..4` token 与 `.heat-color` 色阶样式 |
|
|
151
|
+
| `styles/heatmap.css` | `--color-heatmap-today-ring` token 与 `.heatmap` 网格样式 |
|
|
152
|
+
| `styles/stat-group.css` | `.stat-group` 布局样式 |
|
|
153
|
+
|
|
154
|
+
## 🧩 生态
|
|
155
|
+
|
|
156
|
+
`weimo-ui-stats` 是 weimo-ui 组件家族的一员,唯一的 UI 依赖是 [weimo-ui-core](https://github.com/jiaowenjun/weimo-ui-core) —— 它提供主题 token、悬浮提示与 `cn` 工具。`Heatmap` 与 `StatGroup` 互不依赖,可单独引入。
|
|
157
|
+
|
|
158
|
+
## 🛠️ 本地开发
|
|
159
|
+
|
|
160
|
+
<details>
|
|
161
|
+
<summary>展开查看仓库脚本</summary>
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
pnpm install
|
|
165
|
+
pnpm verify # 类型检查 + 测试 + 打包校验 + 文档站构建
|
|
166
|
+
pnpm site:dev # 本地启动文档站
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
文档站位于 `site/`,推送 `main` 后由 GitHub Actions 自动构建部署到 GitHub Pages。
|
|
170
|
+
|
|
171
|
+
</details>
|
|
172
|
+
|
|
173
|
+
## 许可证
|
|
174
|
+
|
|
175
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* 热力图背景色 token:随热力图色阶模块归属 stats,亮值进 :root、暗值进 .dark,
|
|
2
|
+
与 heat-color.tsx 的 heatColorMap 值保持镜像。 */
|
|
3
|
+
:root {
|
|
4
|
+
--color-heat-0: hsl(0 0% 94%);
|
|
5
|
+
--color-heat-1: hsl(18 62% 89%);
|
|
6
|
+
--color-heat-2: hsl(18 62% 78%);
|
|
7
|
+
--color-heat-3: hsl(18 62% 65%);
|
|
8
|
+
--color-heat-4: hsl(18 62% 52%);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.dark {
|
|
12
|
+
--color-heat-0: hsl(0 0% 19%);
|
|
13
|
+
--color-heat-1: hsl(23 31% 22%);
|
|
14
|
+
--color-heat-2: hsl(23 42% 32%);
|
|
15
|
+
--color-heat-3: hsl(23 50% 44%);
|
|
16
|
+
--color-heat-4: hsl(23 68% 56%);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@layer components {
|
|
20
|
+
.heat-color {
|
|
21
|
+
--heat-color-size: 15px;
|
|
22
|
+
--heat-color-gap: 4px;
|
|
23
|
+
--heat-color-radius: var(--radius-xs);
|
|
24
|
+
|
|
25
|
+
display: inline-flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: var(--heat-color-gap);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.heat-color__swatch {
|
|
31
|
+
display: block;
|
|
32
|
+
width: var(--heat-color-size);
|
|
33
|
+
height: var(--heat-color-size);
|
|
34
|
+
border-radius: var(--heat-color-radius);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@layer utilities {
|
|
39
|
+
.heat-color--0 {
|
|
40
|
+
background: var(--color-heat-0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.heat-color--1 {
|
|
44
|
+
background: var(--color-heat-1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.heat-color--2 {
|
|
48
|
+
background: var(--color-heat-2);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.heat-color--3 {
|
|
52
|
+
background: var(--color-heat-3);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.heat-color--4 {
|
|
56
|
+
background: var(--color-heat-4);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
import './heat-color.css';
|
|
3
|
+
export type HeatColorLevel = 0 | 1 | 2 | 3 | 4;
|
|
4
|
+
export declare const heatColorMap: {
|
|
5
|
+
0: {
|
|
6
|
+
label: string;
|
|
7
|
+
token: string;
|
|
8
|
+
value: {
|
|
9
|
+
light: string;
|
|
10
|
+
dark: string;
|
|
11
|
+
};
|
|
12
|
+
className: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
1: {
|
|
16
|
+
label: string;
|
|
17
|
+
token: string;
|
|
18
|
+
value: {
|
|
19
|
+
light: string;
|
|
20
|
+
dark: string;
|
|
21
|
+
};
|
|
22
|
+
className: string;
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
2: {
|
|
26
|
+
label: string;
|
|
27
|
+
token: string;
|
|
28
|
+
value: {
|
|
29
|
+
light: string;
|
|
30
|
+
dark: string;
|
|
31
|
+
};
|
|
32
|
+
className: string;
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
3: {
|
|
36
|
+
label: string;
|
|
37
|
+
token: string;
|
|
38
|
+
value: {
|
|
39
|
+
light: string;
|
|
40
|
+
dark: string;
|
|
41
|
+
};
|
|
42
|
+
className: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
4: {
|
|
46
|
+
label: string;
|
|
47
|
+
token: string;
|
|
48
|
+
value: {
|
|
49
|
+
light: string;
|
|
50
|
+
dark: string;
|
|
51
|
+
};
|
|
52
|
+
className: string;
|
|
53
|
+
description: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export declare const heatColorLevels: HeatColorLevel[];
|
|
57
|
+
export type HeatColorProps = Omit<HTMLAttributes<HTMLDivElement>, 'aria-label'> & {
|
|
58
|
+
levels?: HeatColorLevel[];
|
|
59
|
+
ariaLabel?: string;
|
|
60
|
+
getLevelLabel?: (level: HeatColorLevel) => string;
|
|
61
|
+
};
|
|
62
|
+
export declare function getHeatColorClassName(level: HeatColorLevel): string;
|
|
63
|
+
export declare function getHeatColorToken(level: HeatColorLevel): string;
|
|
64
|
+
export declare function HeatColor({ ariaLabel, className, getLevelLabel, levels, role, ...props }: HeatColorProps): import("react").JSX.Element;
|
|
65
|
+
//# sourceMappingURL=heat-color.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heat-color.d.ts","sourceRoot":"","sources":["../../../src/components/heatmap/heat-color.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAI3C,OAAO,kBAAkB,CAAA;AAEzB,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAE9C,eAAO,MAAM,YAAY;;QAErB,KAAK;QACL,KAAK;QACL,KAAK;YACH,KAAK;YACL,IAAI;;QAEN,SAAS;QACT,WAAW;;;QAGX,KAAK;QACL,KAAK;QACL,KAAK;YACH,KAAK;YACL,IAAI;;QAEN,SAAS;QACT,WAAW;;;QAGX,KAAK;QACL,KAAK;QACL,KAAK;YACH,KAAK;YACL,IAAI;;QAEN,SAAS;QACT,WAAW;;;QAGX,KAAK;QACL,KAAK;QACL,KAAK;YACH,KAAK;YACL,IAAI;;QAEN,SAAS;QACT,WAAW;;;QAGX,KAAK;QACL,KAAK;QACL,KAAK;YACH,KAAK;YACL,IAAI;;QAEN,SAAS;QACT,WAAW;;CAWb,CAAA;AAEF,eAAO,MAAM,eAAe,EAAsB,cAAc,EAAE,CAAA;AAYlE,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,cAAc,CAAC,cAAc,CAAC,EAC9B,YAAY,CACb,GAAG;IACF,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,MAAM,CAAA;CAClD,CAAA;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,UAE1D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,UAEtD;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAqB,EACrB,SAAS,EACT,aAAuC,EACvC,MAAsB,EACtB,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,cAAc,+BAmBhB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from 'weimo-ui-core/lib/utils';
|
|
3
|
+
import './heat-color.css';
|
|
4
|
+
export const heatColorMap = {
|
|
5
|
+
0: {
|
|
6
|
+
label: '0 级',
|
|
7
|
+
token: '--color-heat-0',
|
|
8
|
+
value: {
|
|
9
|
+
light: 'hsl(0 0% 94%)',
|
|
10
|
+
dark: 'hsl(0 0% 19%)',
|
|
11
|
+
},
|
|
12
|
+
className: 'heat-color--0',
|
|
13
|
+
description: '无记录或最低热力的基础色阶。',
|
|
14
|
+
},
|
|
15
|
+
1: {
|
|
16
|
+
label: '1 级',
|
|
17
|
+
token: '--color-heat-1',
|
|
18
|
+
value: {
|
|
19
|
+
light: 'hsl(18 62% 89%)',
|
|
20
|
+
dark: 'hsl(23 31% 22%)',
|
|
21
|
+
},
|
|
22
|
+
className: 'heat-color--1',
|
|
23
|
+
description: '轻量活动或低热力状态。',
|
|
24
|
+
},
|
|
25
|
+
2: {
|
|
26
|
+
label: '2 级',
|
|
27
|
+
token: '--color-heat-2',
|
|
28
|
+
value: {
|
|
29
|
+
light: 'hsl(18 62% 78%)',
|
|
30
|
+
dark: 'hsl(23 42% 32%)',
|
|
31
|
+
},
|
|
32
|
+
className: 'heat-color--2',
|
|
33
|
+
description: '中低热力状态。',
|
|
34
|
+
},
|
|
35
|
+
3: {
|
|
36
|
+
label: '3 级',
|
|
37
|
+
token: '--color-heat-3',
|
|
38
|
+
value: {
|
|
39
|
+
light: 'hsl(18 62% 65%)',
|
|
40
|
+
dark: 'hsl(23 50% 44%)',
|
|
41
|
+
},
|
|
42
|
+
className: 'heat-color--3',
|
|
43
|
+
description: '中高热力状态。',
|
|
44
|
+
},
|
|
45
|
+
4: {
|
|
46
|
+
label: '4 级',
|
|
47
|
+
token: '--color-heat-4',
|
|
48
|
+
value: {
|
|
49
|
+
light: 'hsl(18 62% 52%)',
|
|
50
|
+
dark: 'hsl(23 68% 56%)',
|
|
51
|
+
},
|
|
52
|
+
className: 'heat-color--4',
|
|
53
|
+
description: '最高热力状态。',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
export const heatColorLevels = [0, 1, 2, 3, 4];
|
|
57
|
+
const defaultLevels = [...heatColorLevels];
|
|
58
|
+
function formatDefaultLevelLabel(level) {
|
|
59
|
+
if (level === 0) {
|
|
60
|
+
return '0 级,无记录';
|
|
61
|
+
}
|
|
62
|
+
return `${level} 级热力`;
|
|
63
|
+
}
|
|
64
|
+
export function getHeatColorClassName(level) {
|
|
65
|
+
return heatColorMap[level].className;
|
|
66
|
+
}
|
|
67
|
+
export function getHeatColorToken(level) {
|
|
68
|
+
return heatColorMap[level].token;
|
|
69
|
+
}
|
|
70
|
+
export function HeatColor({ ariaLabel = '热力图颜色色阶', className, getLevelLabel = formatDefaultLevelLabel, levels = defaultLevels, role, ...props }) {
|
|
71
|
+
return (_jsx("div", { ...props, "aria-label": ariaLabel, className: cn('heat-color', className), role: role ?? 'group', children: levels.map((level) => (_jsx("span", { "aria-label": getLevelLabel(level), className: cn('heat-color__swatch', getHeatColorClassName(level)), "data-level": level, role: "img" }, level))) }));
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=heat-color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heat-color.js","sourceRoot":"","sources":["../../../src/components/heatmap/heat-color.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AAE5C,OAAO,kBAAkB,CAAA;AAIzB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,CAAC,EAAE;QACD,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,gBAAgB;QACvB,KAAK,EAAE;YACL,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,eAAe;SACtB;QACD,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,gBAAgB;KAC9B;IACD,CAAC,EAAE;QACD,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,gBAAgB;QACvB,KAAK,EAAE;YACL,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,iBAAiB;SACxB;QACD,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,aAAa;KAC3B;IACD,CAAC,EAAE;QACD,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,gBAAgB;QACvB,KAAK,EAAE;YACL,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,iBAAiB;SACxB;QACD,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,SAAS;KACvB;IACD,CAAC,EAAE;QACD,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,gBAAgB;QACvB,KAAK,EAAE;YACL,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,iBAAiB;SACxB;QACD,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,SAAS;KACvB;IACD,CAAC,EAAE;QACD,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,gBAAgB;QACvB,KAAK,EAAE;YACL,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,iBAAiB;SACxB;QACD,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,SAAS;KACvB;CAUD,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAqB,CAAA;AAElE,MAAM,aAAa,GAAqB,CAAC,GAAG,eAAe,CAAC,CAAA;AAE5D,SAAS,uBAAuB,CAAC,KAAqB;IACpD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,GAAG,KAAK,MAAM,CAAA;AACvB,CAAC;AAWD,MAAM,UAAU,qBAAqB,CAAC,KAAqB;IACzD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAqB;IACrD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EACxB,SAAS,GAAG,SAAS,EACrB,SAAS,EACT,aAAa,GAAG,uBAAuB,EACvC,MAAM,GAAG,aAAa,EACtB,IAAI,EACJ,GAAG,KAAK,EACO;IACf,OAAO,CACL,iBACM,KAAK,gBACG,SAAS,EACrB,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,EACtC,IAAI,EAAE,IAAI,IAAI,OAAO,YAEpB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACrB,6BACc,aAAa,CAAC,KAAK,CAAC,EAChC,SAAS,EAAE,EAAE,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,gBACrD,KAAK,EAEjB,IAAI,EAAC,KAAK,IADL,KAAK,CAEV,CACH,CAAC,GACE,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type HeatmapDailyCount = {
|
|
2
|
+
date: string;
|
|
3
|
+
count: number;
|
|
4
|
+
};
|
|
5
|
+
export type HeatmapLevel = 0 | 1 | 2 | 3 | 4;
|
|
6
|
+
export type HeatmapCell = {
|
|
7
|
+
date: string;
|
|
8
|
+
count: number;
|
|
9
|
+
level: HeatmapLevel;
|
|
10
|
+
isToday: boolean;
|
|
11
|
+
isActive: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type HeatmapColumn = {
|
|
14
|
+
cells: HeatmapCell[];
|
|
15
|
+
index: number;
|
|
16
|
+
};
|
|
17
|
+
export type HeatmapMonthLabel = {
|
|
18
|
+
name: string;
|
|
19
|
+
columnIndex: number;
|
|
20
|
+
};
|
|
21
|
+
export declare function formatHeatmapDateKey(date: Date): string;
|
|
22
|
+
export declare function getHeatmapLevel(count: number): HeatmapLevel;
|
|
23
|
+
export declare function buildHeatmapCells(dailyCounts: HeatmapDailyCount[], today?: string, activeDate?: string): HeatmapCell[];
|
|
24
|
+
export declare function buildHeatmapColumns(cells: HeatmapCell[]): HeatmapColumn[];
|
|
25
|
+
export declare function buildHeatmapMonthLabels(cells: HeatmapCell[]): HeatmapMonthLabel[];
|
|
26
|
+
//# sourceMappingURL=heatmap-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heatmap-model.d.ts","sourceRoot":"","sources":["../../../src/components/heatmap/heatmap-model.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAE5C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,YAAY,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAsBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,UAM9C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAO3D;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,iBAAiB,EAAE,EAChC,KAAK,SAAmC,EACxC,UAAU,SAAK,iBA8BhB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,mBAWvD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,uBAsB3D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const visibleWeekCount = 13;
|
|
2
|
+
const daysPerWeek = 7;
|
|
3
|
+
function parseDateKey(dateKey) {
|
|
4
|
+
const [year, month, day] = dateKey.split('-').map(Number);
|
|
5
|
+
return new Date(year, month - 1, day);
|
|
6
|
+
}
|
|
7
|
+
function startOfIsoWeek(date) {
|
|
8
|
+
const current = new Date(date);
|
|
9
|
+
const day = current.getDay();
|
|
10
|
+
const diff = day === 0 ? -6 : 1 - day;
|
|
11
|
+
current.setDate(current.getDate() + diff);
|
|
12
|
+
current.setHours(0, 0, 0, 0);
|
|
13
|
+
return current;
|
|
14
|
+
}
|
|
15
|
+
export function formatHeatmapDateKey(date) {
|
|
16
|
+
const year = date.getFullYear();
|
|
17
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
18
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
19
|
+
return `${year}-${month}-${day}`;
|
|
20
|
+
}
|
|
21
|
+
export function getHeatmapLevel(count) {
|
|
22
|
+
if (count <= 0)
|
|
23
|
+
return 0;
|
|
24
|
+
if (count === 1)
|
|
25
|
+
return 1;
|
|
26
|
+
if (count <= 3)
|
|
27
|
+
return 2;
|
|
28
|
+
if (count <= 5)
|
|
29
|
+
return 3;
|
|
30
|
+
return 4;
|
|
31
|
+
}
|
|
32
|
+
export function buildHeatmapCells(dailyCounts, today = formatHeatmapDateKey(new Date()), activeDate = '') {
|
|
33
|
+
const todayDate = parseDateKey(today);
|
|
34
|
+
const endWeekStart = startOfIsoWeek(todayDate);
|
|
35
|
+
const startDate = new Date(endWeekStart);
|
|
36
|
+
startDate.setDate(endWeekStart.getDate() - (visibleWeekCount - 1) * daysPerWeek);
|
|
37
|
+
const countsByDate = new Map(dailyCounts.map((entry) => [entry.date, Math.max(0, entry.count)]));
|
|
38
|
+
const cells = [];
|
|
39
|
+
const cursor = new Date(startDate);
|
|
40
|
+
for (let index = 0; index < visibleWeekCount * daysPerWeek; index += 1) {
|
|
41
|
+
const date = formatHeatmapDateKey(cursor);
|
|
42
|
+
const count = countsByDate.get(date) ?? 0;
|
|
43
|
+
cells.push({
|
|
44
|
+
date,
|
|
45
|
+
count,
|
|
46
|
+
level: getHeatmapLevel(count),
|
|
47
|
+
isToday: date === today,
|
|
48
|
+
isActive: date === activeDate,
|
|
49
|
+
});
|
|
50
|
+
cursor.setDate(cursor.getDate() + 1);
|
|
51
|
+
}
|
|
52
|
+
return cells;
|
|
53
|
+
}
|
|
54
|
+
export function buildHeatmapColumns(cells) {
|
|
55
|
+
const columns = [];
|
|
56
|
+
for (let index = 0; index < cells.length; index += daysPerWeek) {
|
|
57
|
+
columns.push({
|
|
58
|
+
cells: cells.slice(index, index + daysPerWeek),
|
|
59
|
+
index: columns.length,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return columns;
|
|
63
|
+
}
|
|
64
|
+
export function buildHeatmapMonthLabels(cells) {
|
|
65
|
+
const labels = [];
|
|
66
|
+
for (let index = 0; index < cells.length; index += daysPerWeek) {
|
|
67
|
+
const column = cells.slice(index, index + daysPerWeek);
|
|
68
|
+
const monthStart = column.find((cell) => {
|
|
69
|
+
const day = Number(cell.date.split('-')[2]);
|
|
70
|
+
return day === 1;
|
|
71
|
+
});
|
|
72
|
+
if (monthStart) {
|
|
73
|
+
const month = Number(monthStart.date.split('-')[1]);
|
|
74
|
+
labels.push({
|
|
75
|
+
name: `${month}月`,
|
|
76
|
+
columnIndex: index / daysPerWeek,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return labels;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=heatmap-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heatmap-model.js","sourceRoot":"","sources":["../../../src/components/heatmap/heatmap-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* 今日环描边色 token:随 Heatmap 组件归属 stats,亮值进 :root、暗值进 .dark,
|
|
2
|
+
供 .heatmap__cell--today 的 inset 描边消费。 */
|
|
3
|
+
:root {
|
|
4
|
+
--color-heatmap-today-ring: hsl(18.1 71.9% 46.1% / 0.55);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.dark {
|
|
8
|
+
--color-heatmap-today-ring: hsl(0 0% 100% / 0.38);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@layer components {
|
|
12
|
+
.heatmap {
|
|
13
|
+
--heatmap-cell-size: 15px;
|
|
14
|
+
--heatmap-gap: 4px;
|
|
15
|
+
--heatmap-cell-radius: var(--radius-xs);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.heatmap {
|
|
19
|
+
display: flex;
|
|
20
|
+
width: 100%;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
padding: 12px 16px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.heatmap__grid {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: row;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.heatmap__column {
|
|
31
|
+
display: flex;
|
|
32
|
+
width: var(--heatmap-cell-size);
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
margin-right: var(--heatmap-gap);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.heatmap__column:last-child {
|
|
38
|
+
margin-right: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.heatmap__cell {
|
|
42
|
+
width: var(--heatmap-cell-size);
|
|
43
|
+
height: var(--heatmap-cell-size);
|
|
44
|
+
margin: 0 0 var(--heatmap-gap);
|
|
45
|
+
padding: 0;
|
|
46
|
+
border: 0;
|
|
47
|
+
border-radius: var(--heatmap-cell-radius);
|
|
48
|
+
background: var(--color-border);
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
transition:
|
|
51
|
+
opacity 160ms ease,
|
|
52
|
+
transform 160ms ease;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.heatmap__cell:hover {
|
|
56
|
+
opacity: 0.82;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.heatmap__cell:focus-visible {
|
|
60
|
+
outline: 2px solid var(--color-text-primary);
|
|
61
|
+
outline-offset: 2px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.heatmap__cell--active {
|
|
65
|
+
box-shadow: 0 0 0 1.5px var(--color-text-primary);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.heatmap__cell--today {
|
|
69
|
+
box-shadow: inset 0 0 0 1px var(--color-heatmap-today-ring);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.heatmap__cell--today.heatmap__cell--active {
|
|
73
|
+
box-shadow:
|
|
74
|
+
inset 0 0 0 1px var(--color-heatmap-today-ring),
|
|
75
|
+
0 0 0 1.5px var(--color-text-primary);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.heatmap__month,
|
|
79
|
+
.heatmap__month-spacer {
|
|
80
|
+
height: var(--heatmap-cell-size);
|
|
81
|
+
margin-top: var(--heatmap-gap);
|
|
82
|
+
line-height: var(--heatmap-cell-size);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.heatmap__month {
|
|
86
|
+
overflow: visible;
|
|
87
|
+
color: var(--color-text-placeholder);
|
|
88
|
+
font-size: var(--font-size-2xs);
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.heatmap__month-spacer {
|
|
93
|
+
pointer-events: none;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
button.heatmap__cell {
|
|
98
|
+
color: inherit;
|
|
99
|
+
font: inherit;
|
|
100
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
import { type HeatmapCell, type HeatmapDailyCount } from './heatmap-model';
|
|
3
|
+
import './heatmap.css';
|
|
4
|
+
export type { HeatmapCell, HeatmapDailyCount } from './heatmap-model';
|
|
5
|
+
export type HeatmapProps = Omit<HTMLAttributes<HTMLDivElement>, 'onSelect' | 'aria-label'> & {
|
|
6
|
+
dailyCounts?: HeatmapDailyCount[];
|
|
7
|
+
activeDate?: string;
|
|
8
|
+
ariaLabel?: string;
|
|
9
|
+
onDateSelect?: (date: string, cell: HeatmapCell) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function formatHeatmapTooltip(cell: Pick<HeatmapCell, 'count' | 'date'>): string;
|
|
12
|
+
export declare function Heatmap({ activeDate, ariaLabel, className, dailyCounts, onDateSelect, role, ...props }: HeatmapProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=heatmap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../../../src/components/heatmap/heatmap.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAU3C,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAA;AAExB,OAAO,eAAe,CAAA;AAEtB,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAErE,MAAM,MAAM,YAAY,GAAG,IAAI,CAC7B,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,GAAG,YAAY,CAC1B,GAAG;IACF,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAA;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAA;CACzD,CAAA;AAQD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC,UAO1C;AAED,wBAAgB,OAAO,CAAC,EACtB,UAAe,EACf,SAAmB,EACnB,SAAS,EACT,WAAgB,EAChB,YAAY,EACZ,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,YAAY,+BA+Dd"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger, } from 'weimo-ui-core/components/coss/tooltip';
|
|
3
|
+
import { cn } from 'weimo-ui-core/lib/utils';
|
|
4
|
+
import { getHeatColorClassName } from './heat-color';
|
|
5
|
+
import { buildHeatmapCells, buildHeatmapColumns, buildHeatmapMonthLabels, formatHeatmapDateKey, } from './heatmap-model';
|
|
6
|
+
import './heatmap.css';
|
|
7
|
+
function formatCellAriaLabel(cell) {
|
|
8
|
+
const countLabel = `${cell.count} 条记录`;
|
|
9
|
+
return `${cell.date},${countLabel}`;
|
|
10
|
+
}
|
|
11
|
+
export function formatHeatmapTooltip(cell) {
|
|
12
|
+
if (cell.count <= 0) {
|
|
13
|
+
return cell.date;
|
|
14
|
+
}
|
|
15
|
+
return `${cell.date},${cell.count} 条记录`;
|
|
16
|
+
}
|
|
17
|
+
export function Heatmap({ activeDate = '', ariaLabel = '日期热力图', className, dailyCounts = [], onDateSelect, role, ...props }) {
|
|
18
|
+
const today = formatHeatmapDateKey(new Date());
|
|
19
|
+
const cells = buildHeatmapCells(dailyCounts, today, activeDate);
|
|
20
|
+
const columns = buildHeatmapColumns(cells);
|
|
21
|
+
const monthLabels = new Map(buildHeatmapMonthLabels(cells).map((label) => [
|
|
22
|
+
label.columnIndex,
|
|
23
|
+
label.name,
|
|
24
|
+
]));
|
|
25
|
+
return (_jsx("div", { ...props, "aria-label": ariaLabel, className: cn('heatmap', className), role: role ?? 'group', children: _jsx("div", { className: "heatmap__grid", children: _jsx(TooltipProvider, { delay: 180, children: columns.map((column) => {
|
|
26
|
+
const monthLabel = monthLabels.get(column.index);
|
|
27
|
+
return (_jsxs("div", { className: "heatmap__column", children: [column.cells.map((cell) => (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: _jsx("button", { "aria-label": formatCellAriaLabel(cell), className: cn('heatmap__cell', getHeatColorClassName(cell.level), cell.isActive && 'heatmap__cell--active', cell.isToday && 'heatmap__cell--today'), "data-count": cell.count, "data-date": cell.date, "data-level": cell.level, onClick: () => onDateSelect?.(cell.date, cell), type: "button" }) }), _jsx(TooltipPopup, { children: formatHeatmapTooltip(cell) })] }, cell.date))), monthLabel ? (_jsx("span", { className: "heatmap__month", children: monthLabel })) : (_jsx("span", { "aria-hidden": "true", className: "heatmap__month-spacer" }))] }, column.index));
|
|
28
|
+
}) }) }) }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=heatmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heatmap.js","sourceRoot":"","sources":["../../../src/components/heatmap/heatmap.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { Heatmap, type HeatmapProps, } from './heatmap';
|
|
2
|
+
export { buildHeatmapCells, buildHeatmapColumns, buildHeatmapMonthLabels, formatHeatmapDateKey, getHeatmapLevel, type HeatmapCell, type HeatmapColumn, type HeatmapDailyCount, type HeatmapLevel, type HeatmapMonthLabel, } from './heatmap-model';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/heatmap/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,YAAY,GAClB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/heatmap/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,GAER,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,GAMhB,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.stat-group {
|
|
3
|
+
display: flex;
|
|
4
|
+
width: 100%;
|
|
5
|
+
max-width: 243px;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
justify-content: space-between;
|
|
8
|
+
gap: 16px;
|
|
9
|
+
margin: 0 auto 12px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.stat-group__item {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex: 0 1 auto;
|
|
15
|
+
min-width: 0;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
align-items: flex-start;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.stat-group__value {
|
|
21
|
+
color: var(--color-text-secondary);
|
|
22
|
+
font-size: var(--font-size-stat);
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
line-height: 1;
|
|
25
|
+
letter-spacing: -0.05em;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.stat-group__label {
|
|
29
|
+
margin-top: 8px;
|
|
30
|
+
margin-left: 1px;
|
|
31
|
+
color: var(--color-text-placeholder);
|
|
32
|
+
font-size: var(--font-size-sm);
|
|
33
|
+
line-height: 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
import './stat-group.css';
|
|
3
|
+
export type StatGroupItem = {
|
|
4
|
+
key?: string;
|
|
5
|
+
value: ReactNode;
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
export type StatGroupProps = ComponentPropsWithoutRef<'div'> & {
|
|
9
|
+
items?: StatGroupItem[];
|
|
10
|
+
};
|
|
11
|
+
export declare function StatGroup({ children, className, items, role, ...props }: StatGroupProps): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=stat-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stat-group.d.ts","sourceRoot":"","sources":["../../../src/components/stat-group/stat-group.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAIhE,OAAO,kBAAkB,CAAA;AAEzB,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,wBAAwB,CAAC,KAAK,CAAC,GAAG;IAC7D,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;CACxB,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,SAAS,EACT,KAAU,EACV,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,cAAc,+BAYhB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from 'weimo-ui-core/lib/utils';
|
|
3
|
+
import './stat-group.css';
|
|
4
|
+
export function StatGroup({ children, className, items = [], role, ...props }) {
|
|
5
|
+
return (_jsxs("div", { className: cn('stat-group', className), role: role ?? 'group', ...props, children: [items.map((item, index) => (_jsxs("div", { className: "stat-group__item", children: [_jsx("span", { className: "stat-group__value", children: item.value }), _jsx("span", { className: "stat-group__label", children: item.label })] }, item.key ?? index))), children] }));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=stat-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stat-group.js","sourceRoot":"","sources":["../../../src/components/stat-group/stat-group.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AAE5C,OAAO,kBAAkB,CAAA;AAYzB,MAAM,UAAU,SAAS,CAAC,EACxB,QAAQ,EACR,SAAS,EACT,KAAK,GAAG,EAAE,EACV,IAAI,EACJ,GAAG,KAAK,EACO;IACf,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,KAAM,KAAK,aAC1E,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,eAAK,SAAS,EAAC,kBAAkB,aAC/B,eAAM,SAAS,EAAC,mBAAmB,YAAE,IAAI,CAAC,KAAK,GAAQ,EACvD,eAAM,SAAS,EAAC,mBAAmB,YAAE,IAAI,CAAC,KAAK,GAAQ,KAFlB,IAAI,CAAC,GAAG,IAAI,KAAK,CAGlD,CACP,CAAC,EACD,QAAQ,IACL,CACP,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,81 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weimo-ui-stats",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/jiaowenjun/weimo-ui-stats.git"
|
|
10
|
+
},
|
|
11
|
+
"packageManager": "pnpm@12.4.2",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": [
|
|
16
|
+
"**/*.css"
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
"./components/heat-color": {
|
|
25
|
+
"types": "./dist/components/heatmap/heat-color.d.ts",
|
|
26
|
+
"import": "./dist/components/heatmap/heat-color.js"
|
|
27
|
+
},
|
|
28
|
+
"./components/heatmap": {
|
|
29
|
+
"types": "./dist/components/heatmap/index.d.ts",
|
|
30
|
+
"import": "./dist/components/heatmap/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./components/stat-group": {
|
|
33
|
+
"types": "./dist/components/stat-group/stat-group.d.ts",
|
|
34
|
+
"import": "./dist/components/stat-group/stat-group.js"
|
|
35
|
+
},
|
|
36
|
+
"./styles/heat-color.css": {
|
|
37
|
+
"types": "./dist/components/heatmap/heat-color.d.css.ts",
|
|
38
|
+
"default": "./dist/components/heatmap/heat-color.css"
|
|
39
|
+
},
|
|
40
|
+
"./styles/heatmap.css": {
|
|
41
|
+
"types": "./dist/components/heatmap/heatmap.d.css.ts",
|
|
42
|
+
"default": "./dist/components/heatmap/heatmap.css"
|
|
43
|
+
},
|
|
44
|
+
"./styles/stat-group.css": {
|
|
45
|
+
"types": "./dist/components/stat-group/stat-group.d.css.ts",
|
|
46
|
+
"default": "./dist/components/stat-group/stat-group.css"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"clean": "rimraf dist",
|
|
51
|
+
"build": "pnpm clean && tsc -p tsconfig.build.json && node scripts/copy-css.mjs",
|
|
52
|
+
"site:dev": "pnpm build && pnpm --dir site dev",
|
|
53
|
+
"site:build": "pnpm build && pnpm --dir site build",
|
|
54
|
+
"site:preview": "pnpm --dir site preview",
|
|
55
|
+
"typecheck": "tsc -p tsconfig.json --noEmit --pretty false",
|
|
56
|
+
"test:typecheck": "pnpm typecheck",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"check:package": "pnpm build && publint && attw --pack . --profile esm-only --ignore-rules internal-resolution-error",
|
|
59
|
+
"test:site-template": "node scripts/site-template-contract.mjs",
|
|
60
|
+
"verify": "pnpm typecheck && pnpm test && pnpm test:site-template && pnpm check:package && pnpm --dir site build",
|
|
61
|
+
"prepack": "pnpm build"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"react": "^19.0.0",
|
|
65
|
+
"react-dom": "^19.0.0",
|
|
66
|
+
"weimo-ui-core": "~0.2.0"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
70
|
+
"@base-ui/react": "1.9.0",
|
|
71
|
+
"@types/react": "^19.3.0",
|
|
72
|
+
"@types/react-dom": "^19.3.0",
|
|
73
|
+
"publint": "^0.3.25",
|
|
74
|
+
"react": "19.3.0",
|
|
75
|
+
"react-dom": "19.3.0",
|
|
76
|
+
"rimraf": "^6.1.3",
|
|
77
|
+
"typescript": "~7.0.2",
|
|
78
|
+
"vitest": "^5.0.3",
|
|
79
|
+
"weimo-ui-core": "~0.2.1"
|
|
80
|
+
}
|
|
81
|
+
}
|