@svp-chain-sdk/ui 0.1.5 → 0.1.9
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/README.md +190 -300
- package/dist/components/notice-marquee/notice-marquee.d.ts +6 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +783 -584
- package/dist/styles.css +188 -14
- package/dist/tailwind.d.ts +110 -0
- package/dist/tailwind.js +65 -10
- package/dist/wallet.d.ts +338 -0
- package/package.json +15 -6
package/README.md
CHANGED
|
@@ -1,329 +1,224 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @svp-chain-sdk/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SVP Chain SDK 的 React UI 组件包,支持 React 18+,采用 ESM 格式。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 1. Package 使用方式
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## 2. 从公共 npm registry 安装
|
|
10
|
-
|
|
11
|
-
该包以 npm 默认的公共 registry 为标准安装来源,无需额外指定 registry:
|
|
7
|
+
### 安装
|
|
12
8
|
|
|
13
9
|
```sh
|
|
14
|
-
npm install @svp-chain-sdk/ui
|
|
10
|
+
npm install @svp-chain-sdk/ui \
|
|
11
|
+
@rainbow-me/rainbowkit@2.2.11 \
|
|
12
|
+
@tanstack/react-query wagmi viem
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
### React 接入
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
在应用入口导入一次 SDK 和 RainbowKit 样式:
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
```tsx
|
|
20
|
+
import {
|
|
21
|
+
Button,
|
|
22
|
+
ConnectWalletButton,
|
|
23
|
+
FeedbackWidget,
|
|
24
|
+
NoticeMarquee,
|
|
25
|
+
SvpWalletProvider,
|
|
26
|
+
} from '@svp-chain-sdk/ui'
|
|
27
|
+
import '@svp-chain-sdk/ui/styles.css'
|
|
28
|
+
import '@rainbow-me/rainbowkit/styles.css'
|
|
26
29
|
|
|
27
|
-
export
|
|
28
|
-
|
|
30
|
+
export function Root() {
|
|
31
|
+
return (
|
|
32
|
+
<SvpWalletProvider
|
|
33
|
+
appName="SVP App"
|
|
34
|
+
projectId={import.meta.env.VITE_WALLETCONNECT_PROJECT_ID}
|
|
35
|
+
locale="zh-CN"
|
|
36
|
+
>
|
|
37
|
+
<NoticeMarquee />
|
|
38
|
+
<Button>Continue</Button>
|
|
39
|
+
<ConnectWalletButton />
|
|
40
|
+
<FeedbackWidget />
|
|
41
|
+
</SvpWalletProvider>
|
|
42
|
+
)
|
|
29
43
|
}
|
|
30
44
|
```
|
|
31
45
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
## 4. 使用示例
|
|
35
|
-
|
|
36
|
-
所有样式变体都要和基础 class `.ui-button` 组合使用。单独写 `.ui-button-primary` 或 `.ui-button-danger` 只会得到颜色,不会得到布局、间距、焦点态和禁用态。
|
|
37
|
-
|
|
38
|
-
### HTML
|
|
39
|
-
|
|
40
|
-
```html
|
|
41
|
-
<button type="button" class="ui-button ui-button-primary">
|
|
42
|
-
继续
|
|
43
|
-
</button>
|
|
44
|
-
|
|
45
|
-
<button type="button" class="ui-button ui-button-danger" disabled>
|
|
46
|
-
删除
|
|
47
|
-
</button>
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### React
|
|
46
|
+
`projectId` 应来自环境变量,不要把真实 WalletConnect Project ID 提交到仓库。
|
|
51
47
|
|
|
52
|
-
|
|
48
|
+
### Tailwind Provider
|
|
53
49
|
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<div>
|
|
58
|
-
<button type="button" className="ui-button ui-button-primary">
|
|
59
|
-
继续
|
|
60
|
-
</button>
|
|
61
|
-
<button type="button" className="ui-button ui-button-danger">
|
|
62
|
-
删除
|
|
63
|
-
</button>
|
|
64
|
-
</div>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
```
|
|
50
|
+
```ts
|
|
51
|
+
// tailwind.config.ts
|
|
52
|
+
import svpUi from '@svp-chain-sdk/ui/tailwind'
|
|
68
53
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```vue
|
|
72
|
-
<template>
|
|
73
|
-
<div>
|
|
74
|
-
<button type="button" class="ui-button ui-button-primary" @click="submit">
|
|
75
|
-
继续
|
|
76
|
-
</button>
|
|
77
|
-
<button type="button" class="ui-button ui-button-danger" :disabled="pending">
|
|
78
|
-
删除
|
|
79
|
-
</button>
|
|
80
|
-
</div>
|
|
81
|
-
</template>
|
|
82
|
-
|
|
83
|
-
<script setup lang="ts">
|
|
84
|
-
const pending = false
|
|
85
|
-
function submit() {
|
|
86
|
-
// 业务逻辑
|
|
54
|
+
export default {
|
|
55
|
+
plugins: [svpUi],
|
|
87
56
|
}
|
|
88
|
-
</script>
|
|
89
57
|
```
|
|
90
58
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
| --- | --- | --- |
|
|
95
|
-
| `.ui-button` | 按钮基础布局、尺寸、字体、过渡、键盘焦点态和原生禁用态 | 每个按钮都应使用 |
|
|
96
|
-
| `.ui-button-primary` | 主操作背景色、前景色和 hover 色 | 与 `.ui-button` 一起使用 |
|
|
97
|
-
| `.ui-button-danger` | 危险操作背景色、前景色和 hover 色 | 与 `.ui-button` 一起使用 |
|
|
98
|
-
| `.ui-button:focus-visible` | 键盘等触发的可见焦点轮廓 | 由基础 class 自动提供 |
|
|
99
|
-
| `.ui-button:disabled` | 禁止指针事件并降低透明度 | 只匹配支持 `disabled` 的元素及其真实禁用状态 |
|
|
100
|
-
| `.ui-button-primary:hover` | 主操作 hover 背景色 | 由 primary class 自动提供 |
|
|
101
|
-
| `.ui-button-danger:hover` | 危险操作 hover 背景色 | 由 danger class 自动提供 |
|
|
102
|
-
|
|
103
|
-
当前没有 `secondary`、`outline`、`ghost`、尺寸或 loading 等 provider class。不能把可选 React `buttonVariants` 所支持的变体当作 provider class 使用。
|
|
104
|
-
|
|
105
|
-
## 6. 完整样式属性表
|
|
106
|
-
|
|
107
|
-
下表逐项列出 provider 当前注册的样式,数值与源码保持一致。
|
|
108
|
-
|
|
109
|
-
| 选择器 | CSS 属性 | 值 |
|
|
110
|
-
| --- | --- | --- |
|
|
111
|
-
| `.ui-button` | `display` | `inline-flex` |
|
|
112
|
-
| `.ui-button` | `align-items` | `center` |
|
|
113
|
-
| `.ui-button` | `justify-content` | `center` |
|
|
114
|
-
| `.ui-button` | `gap` | `0.5rem` |
|
|
115
|
-
| `.ui-button` | `white-space` | `nowrap` |
|
|
116
|
-
| `.ui-button` | `border-radius` | `0.375rem` |
|
|
117
|
-
| `.ui-button` | `padding` | `0.5rem 1rem` |
|
|
118
|
-
| `.ui-button` | `font-size` | `0.875rem` |
|
|
119
|
-
| `.ui-button` | `line-height` | `1.25rem` |
|
|
120
|
-
| `.ui-button` | `font-weight` | `500` |
|
|
121
|
-
| `.ui-button` | `transition` | `background-color 150ms, color 150ms, border-color 150ms, opacity 150ms` |
|
|
122
|
-
| `.ui-button:focus-visible` | `outline` | `2px solid var(--color-ring, #159bb5)` |
|
|
123
|
-
| `.ui-button:focus-visible` | `outline-offset` | `2px` |
|
|
124
|
-
| `.ui-button:disabled` | `pointer-events` | `none` |
|
|
125
|
-
| `.ui-button:disabled` | `opacity` | `0.5` |
|
|
126
|
-
| `.ui-button-primary` | `background-color` | `var(--color-primary, #159bb5)` |
|
|
127
|
-
| `.ui-button-primary` | `color` | `var(--color-primary-foreground, white)` |
|
|
128
|
-
| `.ui-button-primary:hover` | `background-color` | `color-mix(in srgb, var(--color-primary, #159bb5) 90%, transparent)` |
|
|
129
|
-
| `.ui-button-danger` | `background-color` | `var(--color-destructive, #e5484d)` |
|
|
130
|
-
| `.ui-button-danger` | `color` | `var(--color-destructive-foreground, white)` |
|
|
131
|
-
| `.ui-button-danger:hover` | `background-color` | `color-mix(in srgb, var(--color-destructive, #e5484d) 90%, transparent)` |
|
|
132
|
-
|
|
133
|
-
默认插件还通过 Tailwind `addBase` 注册:
|
|
134
|
-
|
|
135
|
-
```css
|
|
136
|
-
:root {
|
|
137
|
-
--svp-ui-brand: #159bb5;
|
|
138
|
-
}
|
|
59
|
+
```html
|
|
60
|
+
<button type="button" class="ui-button ui-button-primary">Continue</button>
|
|
61
|
+
<button type="button" class="ui-button ui-button-danger">Delete</button>
|
|
139
62
|
```
|
|
140
63
|
|
|
141
|
-
|
|
64
|
+
`.ui-button-primary` 和 `.ui-button-danger` 必须与 `.ui-button` 组合使用。
|
|
142
65
|
|
|
143
|
-
##
|
|
66
|
+
## 2. 支持的 API
|
|
144
67
|
|
|
145
|
-
|
|
68
|
+
### Button
|
|
146
69
|
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
70
|
+
```tsx
|
|
71
|
+
<Button variant="default" size="md">Continue</Button>
|
|
72
|
+
<Button variant="outline" size="sm">Cancel</Button>
|
|
73
|
+
<Button variant="destructive">Delete</Button>
|
|
74
|
+
<Button disabled>Disabled</Button>
|
|
75
|
+
|
|
76
|
+
<Button asChild variant="outline">
|
|
77
|
+
<a href="/docs">Read docs</a>
|
|
78
|
+
</Button>
|
|
155
79
|
```
|
|
156
80
|
|
|
157
|
-
|
|
158
|
-
| --- | --- | --- |
|
|
159
|
-
| `--color-primary` | primary 背景、primary hover 混色 | `#159bb5` |
|
|
160
|
-
| `--color-primary-foreground` | primary 文本 | `white` |
|
|
161
|
-
| `--color-destructive` | danger 背景、danger hover 混色 | `#e5484d` |
|
|
162
|
-
| `--color-destructive-foreground` | danger 文本 | `white` |
|
|
163
|
-
| `--color-ring` | `focus-visible` 轮廓 | `#159bb5` |
|
|
164
|
-
|
|
165
|
-
变量遵循普通 CSS 级联规则,也可以在某个容器上覆盖以实现局部主题。hover 使用 CSS `color-mix()`;目标浏览器需要支持该能力。
|
|
166
|
-
|
|
167
|
-
## 8. 扩展自定义 plugin
|
|
81
|
+
#### ButtonProps
|
|
168
82
|
|
|
169
|
-
|
|
83
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
84
|
+
| --- | --- | --- | --- |
|
|
85
|
+
| `variant` | `'default' \| 'secondary' \| 'outline' \| 'ghost' \| 'destructive'` | `'default'` | 视觉变体 |
|
|
86
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'icon'` | `'md'` | 尺寸 |
|
|
87
|
+
| `asChild` | `boolean` | `false` | 将属性与样式传递给唯一子元素 |
|
|
88
|
+
| `type` | button `type` | `'button'` | 原生按钮类型 |
|
|
89
|
+
| `className` | `string` | 无 | 附加 class |
|
|
90
|
+
| 其他参数 | `React.HTMLAttributes<HTMLElement>` | 无 | 原生属性和事件 |
|
|
170
91
|
|
|
171
|
-
|
|
172
|
-
- `uiNoticeMarqueeComponents`:通知走马灯的完整样式配置对象。
|
|
173
|
-
- `uiComponents`:默认插件注册的完整组件配置,包含按钮和通知走马灯配置。
|
|
92
|
+
### buttonVariants
|
|
174
93
|
|
|
175
|
-
|
|
94
|
+
生成 Button class:
|
|
176
95
|
|
|
177
96
|
```ts
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
addComponents(uiComponents)
|
|
183
|
-
addComponents({
|
|
184
|
-
'.app-toolbar-button': {
|
|
185
|
-
padding: '0.375rem 0.75rem',
|
|
186
|
-
},
|
|
187
|
-
})
|
|
97
|
+
const className = buttonVariants({
|
|
98
|
+
variant: 'outline',
|
|
99
|
+
size: 'sm',
|
|
100
|
+
className: 'my-button',
|
|
188
101
|
})
|
|
189
|
-
|
|
190
|
-
export default {
|
|
191
|
-
plugins: [appUi],
|
|
192
|
-
}
|
|
193
102
|
```
|
|
194
103
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
默认插件与导出的配置对象来自同一份组件定义。请在以下两种方式中二选一,避免重复注册:
|
|
198
|
-
|
|
199
|
-
1. `plugins: [svpUi]`;或
|
|
200
|
-
2. 自定义 plugin 中 `addComponents(uiComponents)`。
|
|
201
|
-
|
|
202
|
-
注意:第二种方式只加入组件规则,不会自动加入默认插件通过 `addBase` 设置的 `--svp-ui-brand`。由于现有按钮规则未使用该变量,这不影响当前按钮样式;如果应用依赖该变量,应自行在 CSS 或自定义 plugin 中声明。
|
|
203
|
-
|
|
204
|
-
## 9. 常见问题
|
|
104
|
+
参数与 `Button` 的 `variant`、`size`、`className` 相同。
|
|
205
105
|
|
|
206
|
-
###
|
|
106
|
+
### SvpWalletProvider
|
|
207
107
|
|
|
208
|
-
|
|
108
|
+
提供 Wagmi、TanStack Query 与 RainbowKit 上下文。应用中只挂载一次。
|
|
209
109
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
110
|
+
```tsx
|
|
111
|
+
<SvpWalletProvider
|
|
112
|
+
projectId={walletConnectProjectId}
|
|
113
|
+
appName="SVP Bridge"
|
|
114
|
+
locale="zh-CN"
|
|
115
|
+
>
|
|
116
|
+
<App />
|
|
117
|
+
</SvpWalletProvider>
|
|
118
|
+
```
|
|
216
119
|
|
|
217
|
-
|
|
120
|
+
#### SvpWalletProviderProps
|
|
218
121
|
|
|
219
|
-
|
|
122
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
123
|
+
| --- | --- | --- | --- |
|
|
124
|
+
| `children` | `React.ReactNode` | 必填 | 应用内容 |
|
|
125
|
+
| `projectId` | `string` | 必填 | WalletConnect Project ID |
|
|
126
|
+
| `appName` | `string` | `'SVP App'` | 应用名称 |
|
|
127
|
+
| `locale` | RainbowKit `Locale` | `'en'` | 钱包弹窗语言 |
|
|
220
128
|
|
|
221
|
-
|
|
222
|
-
import svpUi from '@svp-chain-sdk/ui/tailwind'
|
|
223
|
-
```
|
|
129
|
+
如果应用已经自行挂载 Wagmi、QueryClient 和 RainbowKit Provider,不要再重复使用 `SvpWalletProvider`。
|
|
224
130
|
|
|
225
|
-
|
|
131
|
+
### ConnectWalletButton
|
|
226
132
|
|
|
227
|
-
```
|
|
228
|
-
|
|
133
|
+
```tsx
|
|
134
|
+
<ConnectWalletButton
|
|
135
|
+
labels={{
|
|
136
|
+
connect: '连接钱包',
|
|
137
|
+
wrongNetwork: '网络错误',
|
|
138
|
+
}}
|
|
139
|
+
showChain
|
|
140
|
+
/>
|
|
229
141
|
```
|
|
230
142
|
|
|
231
|
-
|
|
143
|
+
#### ConnectWalletButtonProps
|
|
232
144
|
|
|
233
|
-
|
|
145
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
146
|
+
| --- | --- | --- | --- |
|
|
147
|
+
| `className` | `string` | 无 | 钱包操作按钮附加 class |
|
|
148
|
+
| `labels.connect` | `string` | `'Connect Wallet'` | 未连接文案 |
|
|
149
|
+
| `labels.wrongNetwork` | `string` | `'Wrong Network'` | 错误网络文案 |
|
|
150
|
+
| `showChain` | `boolean` | `true` | 已连接后是否展示网络按钮 |
|
|
234
151
|
|
|
235
|
-
|
|
152
|
+
组件自动处理未连接、错误网络和已连接状态。
|
|
236
153
|
|
|
237
|
-
|
|
154
|
+
### createSvpWalletConfig
|
|
238
155
|
|
|
239
|
-
|
|
156
|
+
创建 SDK 默认 Wagmi 配置:
|
|
240
157
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
npm run release:minor
|
|
247
|
-
npm run release:major
|
|
158
|
+
```ts
|
|
159
|
+
const config = createSvpWalletConfig({
|
|
160
|
+
projectId: walletConnectProjectId,
|
|
161
|
+
appName: 'SVP App',
|
|
162
|
+
})
|
|
248
163
|
```
|
|
249
164
|
|
|
250
|
-
|
|
165
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| `projectId` | `string` | 必填 | WalletConnect Project ID |
|
|
168
|
+
| `appName` | `string` | `'SVP App'` | 应用名称 |
|
|
251
169
|
|
|
252
|
-
|
|
253
|
-
2. 通过后使用 `npm version <type> --no-git-tag-version` 更新 `package.json`,不创建 Git commit/tag。
|
|
254
|
-
3. 使用 `pnpm install --lockfile-only --ignore-scripts` 同步仓库的 `pnpm-lock.yaml`,再执行 `npm publish --access public`。
|
|
255
|
-
|
|
256
|
-
首次发布或正式发布前,建议先运行完整的安全演练:
|
|
257
|
-
|
|
258
|
-
```sh
|
|
259
|
-
npm run release -- --dry-run
|
|
260
|
-
npm run release:minor -- --dry-run
|
|
261
|
-
```
|
|
170
|
+
默认包含 Sepolia、SVP Testnet、Arbitrum Sepolia,以及 SVP Wallet、MetaMask、OKX、Rainbow、WalletConnect、Base Account 和 Safe。
|
|
262
171
|
|
|
263
|
-
|
|
172
|
+
### 钱包工具与常量
|
|
264
173
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
174
|
+
| 导出 | 说明 |
|
|
175
|
+
| --- | --- |
|
|
176
|
+
| `resolveSvpProvider()` | 从 `window.ethereum` 或 provider 列表查找 SVP Wallet |
|
|
177
|
+
| `resolveSvpProviderForConnection(redirect?)` | 查找 SVP Wallet;未安装时跳转下载页 |
|
|
178
|
+
| `svpWallet()` | RainbowKit 的 SVP Wallet 定义 |
|
|
179
|
+
| `svpTestnet` | SVP Testnet 链配置 |
|
|
180
|
+
| `walletDefaults` | 默认应用名、链和钱包分组 |
|
|
181
|
+
| `walletTheme` | SDK RainbowKit 主题 |
|
|
182
|
+
| `SVP_WALLET_DOWNLOAD_URL` | SVP Wallet Chrome Web Store 地址 |
|
|
268
183
|
|
|
269
|
-
|
|
184
|
+
### FeedbackWidget
|
|
270
185
|
|
|
271
|
-
|
|
186
|
+
页面右侧垂直居中的悬浮入口,点击后在新标签页打开内置 Google Form。
|
|
272
187
|
|
|
273
188
|
```tsx
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
export function AppShell() {
|
|
278
|
-
return (
|
|
279
|
-
<>
|
|
280
|
-
{/* 页面与路由内容 */}
|
|
281
|
-
<FeedbackWidget />
|
|
282
|
-
</>
|
|
283
|
-
)
|
|
284
|
-
}
|
|
189
|
+
<FeedbackWidget />
|
|
190
|
+
<FeedbackWidget className="my-feedback" />
|
|
285
191
|
```
|
|
286
192
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
组件使用带有 `target="_blank"` 和 `rel="noopener noreferrer"` 的链接打开表单,不读取、存储或转发表单内容,也不依赖 iframe 或消费站点的 `frame-src` 配置。
|
|
193
|
+
#### FeedbackWidgetProps
|
|
290
194
|
|
|
291
|
-
|
|
195
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
196
|
+
| --- | --- | --- | --- |
|
|
197
|
+
| `className` | `string` | 无 | 附加 class |
|
|
292
198
|
|
|
293
|
-
`
|
|
199
|
+
内置地址:`https://forms.gle/6semmo55DSLtcbnw7`。链接使用 `target="_blank"` 和 `rel="noopener noreferrer"`。
|
|
294
200
|
|
|
295
|
-
|
|
201
|
+
### NoticeMarquee
|
|
296
202
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
| 导入路径 | 当前内容 |
|
|
300
|
-
| --- | --- |
|
|
301
|
-
| `@svp-chain-sdk/ui/tailwind` | 默认 Tailwind plugin;具名 `uiButtonComponents`、`uiNoticeMarqueeComponents`、`uiComponents` |
|
|
302
|
-
| `@svp-chain-sdk/ui` | React `Button`、零配置 `NoticeMarquee` 与 `FeedbackWidget`、相关类型和常量、`buttonVariants` 和 `cn` |
|
|
303
|
-
| `@svp-chain-sdk/ui/styles.css` | 包构建产出的 Tailwind v4 CSS 样式入口;当前不包含 provider 的 `.ui-button*` 规则 |
|
|
203
|
+
顶部居中的高层级通知浮层,默认距顶部 `100px`。默认读取 SDK 内置 IPFS JSON,根据浏览器语言选择文案,并每 5 分钟静默刷新。用户可以点击“已知晓”或关闭按钮。
|
|
304
204
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
## 13. React NoticeMarquee 通知走马灯
|
|
308
|
-
|
|
309
|
-
`NoticeMarquee` 是零配置公共组件。业务页面只需要渲染组件,无需传入通知内容或文件地址:
|
|
205
|
+
- **已知晓**:记录当前完整公告快照,本轮公告不再显示;远程公告内容发生变化后会再次显示。
|
|
206
|
+
- **关闭**:只关闭当前页面实例,不写入 localStorage;刷新页面后仍会再次显示。
|
|
310
207
|
|
|
311
208
|
```tsx
|
|
312
|
-
|
|
209
|
+
<NoticeMarquee />
|
|
313
210
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
211
|
+
<NoticeMarquee
|
|
212
|
+
url="https://example.com/notice.json"
|
|
213
|
+
storageKey="my-app:notice"
|
|
214
|
+
refreshIntervalMs={5 * 60 * 1000}
|
|
215
|
+
acknowledgeLabel="已知晓"
|
|
216
|
+
closeLabel="关闭通知"
|
|
217
|
+
className="my-notice"
|
|
218
|
+
/>
|
|
322
219
|
```
|
|
323
220
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
服务端 JSON 格式:
|
|
221
|
+
远程 JSON:
|
|
327
222
|
|
|
328
223
|
```json
|
|
329
224
|
{
|
|
@@ -333,63 +228,58 @@ export function Layout() {
|
|
|
333
228
|
}
|
|
334
229
|
```
|
|
335
230
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
浏览器会在 `localStorage` 的 `DEFAULT_NOTICE_STORAGE_KEY` 下保存:
|
|
339
|
-
|
|
340
|
-
```json
|
|
341
|
-
{
|
|
342
|
-
"seenAt": 1789445000000,
|
|
343
|
-
"content": "{\"en\":\"English notice\",\"fr\":\"Notification française\",\"zh\":\"中文通知\"}"
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
`content` 不是当前语言的展示文案,而是完整远程公告对象的 canonical JSON 快照:对象 key 会递归排序,因此属性顺序不同但内容相同的 JSON 会得到相同值。展示文本仍独立地按 `navigator.language` 选择。
|
|
231
|
+
中文读取 `zh`,法语读取 `fr`,其他语言读取 `en`;缺失时回退到 `en`,再回退到第一个非空字符串。内容按纯文本渲染。组件通过 localStorage 记录完整公告快照,相同公告不重复播放。
|
|
348
232
|
|
|
349
|
-
|
|
233
|
+
#### NoticeMarqueeProps
|
|
350
234
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
235
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
236
|
+
| --- | --- | --- | --- |
|
|
237
|
+
| `url` | `string` | `DEFAULT_NOTICE_URL` | 远程 JSON 地址,需要允许 CORS |
|
|
238
|
+
| `storageKey` | `string` | `DEFAULT_NOTICE_STORAGE_KEY` | localStorage key |
|
|
239
|
+
| `refreshIntervalMs` | `number` | `DEFAULT_NOTICE_REFRESH_INTERVAL_MS` | 静默刷新间隔;小于等于 0 时关闭轮询 |
|
|
240
|
+
| `acknowledgeLabel` | `string` | `'已知晓'` | 确认按钮文案 |
|
|
241
|
+
| `closeLabel` | `string` | `'关闭通知'` | 关闭按钮的无障碍文案与 title |
|
|
242
|
+
| `className` | `string` | 无 | 附加 class |
|
|
357
243
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
样式与 `dex-website-frontend` Footer 的 InfiniteMarquee 保持一致:可视区宽度为 `16rem`,两份相同内容首尾衔接,轨道从 `0` 平移至 `-50%`,默认周期为 `32s`,仅在 hover 时原地暂停。可通过 CSS 变量调整滚动周期:
|
|
244
|
+
桌面端默认宽度最大 `42rem`、距顶部 `100px`、层级 `2147483647`,动画周期 `32s`,hover 时暂停。560px 以下改为距安全区顶部 16px 的自适应卡片并停止滚动,以保证长文本可读。动画周期可以通过 CSS 调整:
|
|
361
245
|
|
|
362
246
|
```css
|
|
363
247
|
:root {
|
|
364
|
-
--ui-notice-marquee-duration:
|
|
248
|
+
--ui-notice-marquee-duration: 24s;
|
|
365
249
|
}
|
|
366
250
|
```
|
|
367
251
|
|
|
368
|
-
|
|
252
|
+
| 常量 | 说明 |
|
|
253
|
+
| --- | --- |
|
|
254
|
+
| `DEFAULT_NOTICE_URL` | 默认通知 JSON 地址 |
|
|
255
|
+
| `DEFAULT_NOTICE_STORAGE_KEY` | 默认 localStorage key |
|
|
256
|
+
| `DEFAULT_NOTICE_REFRESH_INTERVAL_MS` | 默认刷新间隔 `5 * 60 * 1000` |
|
|
369
257
|
|
|
370
|
-
|
|
371
|
-
<NoticeMarquee
|
|
372
|
-
url="https://example.com/notice.json"
|
|
373
|
-
storageKey="my-app:notice"
|
|
374
|
-
refreshIntervalMs={5 * 60 * 1000}
|
|
375
|
-
/>
|
|
376
|
-
```
|
|
258
|
+
### cn
|
|
377
259
|
|
|
378
|
-
|
|
260
|
+
合并条件 class 并处理 Tailwind class 冲突:
|
|
379
261
|
|
|
380
262
|
```ts
|
|
381
|
-
|
|
382
|
-
DEFAULT_NOTICE_REFRESH_INTERVAL_MS,
|
|
383
|
-
DEFAULT_NOTICE_STORAGE_KEY,
|
|
384
|
-
DEFAULT_NOTICE_URL,
|
|
385
|
-
NoticeMarquee,
|
|
386
|
-
type NoticeMarqueeProps,
|
|
387
|
-
} from '@svp-chain-sdk/ui'
|
|
263
|
+
const className = cn('px-4', active && 'bg-primary', disabled && 'opacity-50')
|
|
388
264
|
```
|
|
389
265
|
|
|
390
|
-
|
|
266
|
+
```ts
|
|
267
|
+
cn(...inputs: ClassValue[]): string
|
|
268
|
+
```
|
|
391
269
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
270
|
+
### Tailwind Provider 导出
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
import svpUi, {
|
|
274
|
+
uiButtonComponents,
|
|
275
|
+
uiNoticeMarqueeComponents,
|
|
276
|
+
uiComponents,
|
|
277
|
+
} from '@svp-chain-sdk/ui/tailwind'
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
| 导出 | 说明 |
|
|
281
|
+
| --- | --- |
|
|
282
|
+
| `svpUi` | 默认 Tailwind plugin |
|
|
283
|
+
| `uiButtonComponents` | 按钮 class 配置 |
|
|
284
|
+
| `uiNoticeMarqueeComponents` | 走马灯 class 与动画配置 |
|
|
285
|
+
| `uiComponents` | 全部 provider 配置 |
|
|
@@ -5,14 +5,16 @@ export declare const DEFAULT_NOTICE_REFRESH_INTERVAL_MS: number;
|
|
|
5
5
|
export type NoticeMarqueeProps = {
|
|
6
6
|
/** Optional override for the SDK default multilingual JSON URL. */
|
|
7
7
|
url?: string;
|
|
8
|
-
/** Optional override for the localStorage key used to remember
|
|
8
|
+
/** Optional override for the localStorage key used to remember acknowledged content. */
|
|
9
9
|
storageKey?: string;
|
|
10
10
|
/** Optional override for the default five-minute silent refresh interval. */
|
|
11
11
|
refreshIntervalMs?: number;
|
|
12
|
+
acknowledgeLabel?: string;
|
|
13
|
+
closeLabel?: string;
|
|
12
14
|
className?: string;
|
|
13
15
|
};
|
|
14
16
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
+
* Fixed remote notice. Acknowledging persists the current payload; closing only
|
|
18
|
+
* dismisses it for the current mounted page, so a browser refresh shows it again.
|
|
17
19
|
*/
|
|
18
|
-
export declare function NoticeMarquee({ url, storageKey, refreshIntervalMs, className, }?: NoticeMarqueeProps): React.JSX.Element | null;
|
|
20
|
+
export declare function NoticeMarquee({ url, storageKey, refreshIntervalMs, acknowledgeLabel, closeLabel, className, }?: NoticeMarqueeProps): React.JSX.Element | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { Button, buttonVariants, DEFAULT_NOTICE_REFRESH_INTERVAL_MS, DEFAULT_NOTICE_STORAGE_KEY, DEFAULT_NOTICE_URL, FeedbackWidget, NoticeMarquee, } from './components';
|
|
2
2
|
export type { ButtonProps, FeedbackWidgetProps, NoticeMarqueeProps, } from './components';
|
|
3
3
|
export { cn } from './lib/utils';
|
|
4
|
+
export { ConnectWalletButton, createSvpWalletConfig, resolveSvpProvider, resolveSvpProviderForConnection, SVP_WALLET_DOWNLOAD_URL, svpTestnet, svpWallet, SvpWalletProvider, walletDefaults, walletTheme, } from './wallet';
|
|
5
|
+
export type { ConnectWalletButtonProps, ConnectWalletLabels, CreateSvpWalletConfigOptions, SvpWalletProviderProps, SvpWalletDefaults, } from './wallet';
|