@svp-chain-sdk/ui 0.1.4 → 0.1.6

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 CHANGED
@@ -1,357 +1,285 @@
1
- # `@svp-chain-sdk/ui` Tailwind Provider 使用指南
1
+ # @svp-chain-sdk/ui
2
2
 
3
- ## 1. 适用范围
3
+ SVP Chain SDK 的 React UI 组件包,支持 React 18+,采用 ESM 格式。
4
4
 
5
- `@svp-chain-sdk/ui` 提供 Tailwind provider,也提供 React 钱包公共能力。钱包支持链、钱包分组、RainbowKit 主题、SVP Wallet 检测与安装地址统一维护在 `src/wallet.tsx` `walletDefaults` 及相关导出中。
5
+ ## 1. Package 使用方式
6
6
 
7
- React 项目可直接复用 Provider 和连接按钮:
7
+ ### 安装
8
+
9
+ ```sh
10
+ npm install @svp-chain-sdk/ui \
11
+ @rainbow-me/rainbowkit@2.2.11 \
12
+ @tanstack/react-query wagmi viem
13
+ ```
14
+
15
+ ### React 接入
16
+
17
+ 在应用入口导入一次 SDK 和 RainbowKit 样式:
8
18
 
9
19
  ```tsx
10
20
  import {
21
+ Button,
11
22
  ConnectWalletButton,
23
+ FeedbackWidget,
24
+ NoticeMarquee,
12
25
  SvpWalletProvider,
13
26
  } from '@svp-chain-sdk/ui'
27
+ import '@svp-chain-sdk/ui/styles.css'
14
28
  import '@rainbow-me/rainbowkit/styles.css'
15
29
 
16
- export function App() {
30
+ export function Root() {
17
31
  return (
18
- <SvpWalletProvider appName="SVP Bridge" projectId={walletConnectProjectId}>
19
- <ConnectWalletButton
20
- labels={{ connect: '连接钱包', wrongNetwork: '网络错误' }}
21
- />
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 />
22
41
  </SvpWalletProvider>
23
42
  )
24
43
  }
25
44
  ```
26
45
 
27
- 消费项目需要安装本包声明的 React、RainbowKit、TanStack Query、Wagmi 和 Viem peer dependencies。业务层只传应用名、WalletConnect Project ID 和本地化文案;默认链、钱包顺序、弹窗主题与 SVP Wallet 行为由 SDK 统一提供。
46
+ `projectId` 应来自环境变量,不要把真实 WalletConnect Project ID 提交到仓库。
28
47
 
29
- ### 在现有项目中接入(以 swap-v2 为例)
48
+ ### Tailwind Provider
30
49
 
31
- 1. 安装公共包及 peer dependencies:
32
-
33
- ```sh
34
- pnpm add @svp-chain-sdk/ui @rainbow-me/rainbowkit @tanstack/react-query wagmi viem
35
- ```
36
-
37
- 本地联调尚未发布的 SDK 时,可以把依赖临时指向仓库中的 UI 包:
50
+ ```ts
51
+ // tailwind.config.ts
52
+ import svpUi from '@svp-chain-sdk/ui/tailwind'
38
53
 
39
- ```json
40
- {
41
- "dependencies": {
42
- "@svp-chain-sdk/ui": "file:../svp-chain-sdk-monorepo/packages/ui"
43
- }
54
+ export default {
55
+ plugins: [svpUi],
44
56
  }
45
57
  ```
46
58
 
47
- 2. 在应用入口导入 SDK 与 RainbowKit 样式,并用 `SvpWalletProvider` 包裹应用。`projectId` 应读取项目自己的 `VITE_WALLETCONNECT_PROJECT_ID`,不要提交真实凭据:
48
-
49
- ```tsx
50
- import { SvpWalletProvider } from '@svp-chain-sdk/ui'
51
- import '@svp-chain-sdk/ui/styles.css'
52
- import '@rainbow-me/rainbowkit/styles.css'
53
-
54
- createRoot(document.getElementById('root')!).render(
55
- <SvpWalletProvider
56
- appName="NovaSwap"
57
- projectId={import.meta.env.VITE_WALLETCONNECT_PROJECT_ID}
58
- locale="zh-CN"
59
- >
60
- <App />
61
- </SvpWalletProvider>,
62
- )
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>
63
62
  ```
64
63
 
65
- 如果项目已经自行声明了 `WagmiProvider`、`QueryClientProvider` 和 `RainbowKitProvider`,应删除重复 Provider,避免出现两个 Wagmi/Query Client 上下文。默认网络、钱包排序、SVP Wallet 图标、安装跳转和弹窗主题由 SDK 提供。
64
+ `.ui-button-primary` 和 `.ui-button-danger` 必须与 `.ui-button` 组合使用。
66
65
 
67
- 3. Header 或其他业务组件中直接使用连接按钮:
66
+ ## 2. 支持的 API
68
67
 
69
- ```tsx
70
- import { ConnectWalletButton } from '@svp-chain-sdk/ui'
68
+ ### Button
71
69
 
72
- export function HeaderWallet() {
73
- return (
74
- <ConnectWalletButton
75
- labels={{
76
- connect: '连接钱包',
77
- wrongNetwork: '网络错误',
78
- }}
79
- />
80
- )
81
- }
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>
82
79
  ```
83
80
 
84
- 按钮会自动处理未连接、错误网络和已连接三种状态。`showChain={false}` 可以在已连接时隐藏独立网络按钮;`className` 只应用到钱包操作按钮。SVP Wallet 图标已经随 npm 包构建,不需要消费项目把图片复制到 `public`。
85
-
86
- 4. 升级 SDK 后执行项目自身的测试与生产构建,至少确认连接弹窗、SVP Wallet 图标、未安装跳转、网络切换和账户弹窗正常。
87
-
88
- 这是**框架无关、非 React 组件优先**的模式。包根入口仍提供可选的 React `Button`、`buttonVariants` 和 `cn`,也导出 `@svp-chain-sdk/ui/styles.css` 样式入口,但它们不是本文的主要接入方式。目前 Tailwind provider 只注册按钮相关 class,不应假定它包含表单、弹窗或其他尚未实现的组件。
81
+ #### ButtonProps
89
82
 
90
- ## 2. 从公共 npm registry 安装
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>` | 无 | 原生属性和事件 |
91
91
 
92
- 该包以 npm 默认的公共 registry 为标准安装来源,无需额外指定 registry:
92
+ ### buttonVariants
93
93
 
94
- ```sh
95
- npm install @svp-chain-sdk/ui
96
- ```
97
-
98
- 消费方还需要使用 Tailwind CSS;该包的 provider 构建自 Tailwind v4,目前包本身不会把 `tailwindcss` 作为运行时依赖安装到消费项目中。
99
-
100
- ## 3. 注册 Tailwind provider
101
-
102
- 在消费项目的 Tailwind 配置中引入默认导出,并且只注册一次:
94
+ 生成 Button class:
103
95
 
104
96
  ```ts
105
- // tailwind.config.ts(Tailwind v4 兼容配置)
106
- import svpUi from '@svp-chain-sdk/ui/tailwind'
107
-
108
- export default {
109
- plugins: [svpUi],
110
- }
97
+ const className = buttonVariants({
98
+ variant: 'outline',
99
+ size: 'sm',
100
+ className: 'my-button',
101
+ })
111
102
  ```
112
103
 
113
- `@svp-chain-sdk/ui` ESM-only 包,因此配置文件和构建工具必须支持 ESM `import`。注册后仍需由消费项目现有的 Tailwind 构建流程产出并加载 CSS。
114
-
115
- ## 4. 使用示例
104
+ 参数与 `Button` `variant`、`size`、`className` 相同。
116
105
 
117
- 所有样式变体都要和基础 class `.ui-button` 组合使用。单独写 `.ui-button-primary` 或 `.ui-button-danger` 只会得到颜色,不会得到布局、间距、焦点态和禁用态。
118
-
119
- ### HTML
120
-
121
- ```html
122
- <button type="button" class="ui-button ui-button-primary">
123
- 继续
124
- </button>
125
-
126
- <button type="button" class="ui-button ui-button-danger" disabled>
127
- 删除
128
- </button>
129
- ```
106
+ ### SvpWalletProvider
130
107
 
131
- ### React
132
-
133
- 这里使用原生元素和 `className`,不依赖包根入口的 React `Button`:
108
+ 提供 Wagmi、TanStack Query 与 RainbowKit 上下文。应用中只挂载一次。
134
109
 
135
110
  ```tsx
136
- export function Actions() {
137
- return (
138
- <div>
139
- <button type="button" className="ui-button ui-button-primary">
140
- 继续
141
- </button>
142
- <button type="button" className="ui-button ui-button-danger">
143
- 删除
144
- </button>
145
- </div>
146
- )
147
- }
148
- ```
149
-
150
- ### Vue
151
-
152
- ```vue
153
- <template>
154
- <div>
155
- <button type="button" class="ui-button ui-button-primary" @click="submit">
156
- 继续
157
- </button>
158
- <button type="button" class="ui-button ui-button-danger" :disabled="pending">
159
- 删除
160
- </button>
161
- </div>
162
- </template>
163
-
164
- <script setup lang="ts">
165
- const pending = false
166
- function submit() {
167
- // 业务逻辑
168
- }
169
- </script>
111
+ <SvpWalletProvider
112
+ projectId={walletConnectProjectId}
113
+ appName="SVP Bridge"
114
+ locale="zh-CN"
115
+ >
116
+ <App />
117
+ </SvpWalletProvider>
170
118
  ```
171
119
 
172
- ## 5. 现有 class 与组合规则
173
-
174
- | Class / 状态 | 用途 | 组合规则 |
175
- | --- | --- | --- |
176
- | `.ui-button` | 按钮基础布局、尺寸、字体、过渡、键盘焦点态和原生禁用态 | 每个按钮都应使用 |
177
- | `.ui-button-primary` | 主操作背景色、前景色和 hover 色 | 与 `.ui-button` 一起使用 |
178
- | `.ui-button-danger` | 危险操作背景色、前景色和 hover 色 | 与 `.ui-button` 一起使用 |
179
- | `.ui-button:focus-visible` | 键盘等触发的可见焦点轮廓 | 由基础 class 自动提供 |
180
- | `.ui-button:disabled` | 禁止指针事件并降低透明度 | 只匹配支持 `disabled` 的元素及其真实禁用状态 |
181
- | `.ui-button-primary:hover` | 主操作 hover 背景色 | 由 primary class 自动提供 |
182
- | `.ui-button-danger:hover` | 危险操作 hover 背景色 | 由 danger class 自动提供 |
183
-
184
- 当前没有 `secondary`、`outline`、`ghost`、尺寸或 loading 等 provider class。不能把可选 React `buttonVariants` 所支持的变体当作 provider class 使用。
185
-
186
- ## 6. 完整样式属性表
187
-
188
- 下表逐项列出 provider 当前注册的样式,数值与源码保持一致。
189
-
190
- | 选择器 | CSS 属性 | 值 |
191
- | --- | --- | --- |
192
- | `.ui-button` | `display` | `inline-flex` |
193
- | `.ui-button` | `align-items` | `center` |
194
- | `.ui-button` | `justify-content` | `center` |
195
- | `.ui-button` | `gap` | `0.5rem` |
196
- | `.ui-button` | `white-space` | `nowrap` |
197
- | `.ui-button` | `border-radius` | `0.375rem` |
198
- | `.ui-button` | `padding` | `0.5rem 1rem` |
199
- | `.ui-button` | `font-size` | `0.875rem` |
200
- | `.ui-button` | `line-height` | `1.25rem` |
201
- | `.ui-button` | `font-weight` | `500` |
202
- | `.ui-button` | `transition` | `background-color 150ms, color 150ms, border-color 150ms, opacity 150ms` |
203
- | `.ui-button:focus-visible` | `outline` | `2px solid var(--color-ring, #159bb5)` |
204
- | `.ui-button:focus-visible` | `outline-offset` | `2px` |
205
- | `.ui-button:disabled` | `pointer-events` | `none` |
206
- | `.ui-button:disabled` | `opacity` | `0.5` |
207
- | `.ui-button-primary` | `background-color` | `var(--color-primary, #159bb5)` |
208
- | `.ui-button-primary` | `color` | `var(--color-primary-foreground, white)` |
209
- | `.ui-button-primary:hover` | `background-color` | `color-mix(in srgb, var(--color-primary, #159bb5) 90%, transparent)` |
210
- | `.ui-button-danger` | `background-color` | `var(--color-destructive, #e5484d)` |
211
- | `.ui-button-danger` | `color` | `var(--color-destructive-foreground, white)` |
212
- | `.ui-button-danger:hover` | `background-color` | `color-mix(in srgb, var(--color-destructive, #e5484d) 90%, transparent)` |
213
-
214
- 默认插件还通过 Tailwind `addBase` 注册:
215
-
216
- ```css
217
- :root {
218
- --svp-ui-brand: #159bb5;
219
- }
220
- ```
120
+ #### SvpWalletProviderProps
221
121
 
222
- 该变量目前仅被注册,现有按钮规则没有引用它。按钮实际读取的是下一节中的五个 `--color-*` 变量。
122
+ | 参数 | 类型 | 默认值 | 说明 |
123
+ | --- | --- | --- | --- |
124
+ | `children` | `React.ReactNode` | 必填 | 应用内容 |
125
+ | `projectId` | `string` | 必填 | WalletConnect Project ID |
126
+ | `appName` | `string` | `'SVP App'` | 应用名称 |
127
+ | `locale` | RainbowKit `Locale` | `'en'` | 钱包弹窗语言 |
223
128
 
224
- ## 7. CSS variables 自定义主题
129
+ 如果应用已经自行挂载 Wagmi、QueryClient RainbowKit Provider,不要再重复使用 `SvpWalletProvider`。
225
130
 
226
- 在消费项目加载的 CSS 中覆盖变量即可,无需复制组件定义:
131
+ ### ConnectWalletButton
227
132
 
228
- ```css
229
- :root {
230
- --color-primary: #006adc;
231
- --color-primary-foreground: white;
232
- --color-destructive: #d13415;
233
- --color-destructive-foreground: white;
234
- --color-ring: #006adc;
235
- }
133
+ ```tsx
134
+ <ConnectWalletButton
135
+ labels={{
136
+ connect: '连接钱包',
137
+ wrongNetwork: '网络错误',
138
+ }}
139
+ showChain
140
+ />
236
141
  ```
237
142
 
238
- | 变量 | 使用位置 | 未设置时的 fallback |
239
- | --- | --- | --- |
240
- | `--color-primary` | primary 背景、primary hover 混色 | `#159bb5` |
241
- | `--color-primary-foreground` | primary 文本 | `white` |
242
- | `--color-destructive` | danger 背景、danger hover 混色 | `#e5484d` |
243
- | `--color-destructive-foreground` | danger 文本 | `white` |
244
- | `--color-ring` | `focus-visible` 轮廓 | `#159bb5` |
245
-
246
- 变量遵循普通 CSS 级联规则,也可以在某个容器上覆盖以实现局部主题。hover 使用 CSS `color-mix()`;目标浏览器需要支持该能力。
143
+ #### ConnectWalletButtonProps
247
144
 
248
- ## 8. 扩展自定义 plugin
145
+ | 参数 | 类型 | 默认值 | 说明 |
146
+ | --- | --- | --- | --- |
147
+ | `className` | `string` | 无 | 钱包操作按钮附加 class |
148
+ | `labels.connect` | `string` | `'Connect Wallet'` | 未连接文案 |
149
+ | `labels.wrongNetwork` | `string` | `'Wrong Network'` | 错误网络文案 |
150
+ | `showChain` | `boolean` | `true` | 已连接后是否展示网络按钮 |
249
151
 
250
- `@svp-chain-sdk/ui/tailwind` 提供两个具名导出:
152
+ 组件自动处理未连接、错误网络和已连接状态。
251
153
 
252
- - `uiButtonComponents`:当前按钮组件配置对象。
253
- - `uiComponents`:默认插件注册的完整组件配置;当前它与 `uiButtonComponents` 是同一个对象。未来若增加其他组件,应优先使用 `uiComponents` 来继承完整配置。
154
+ ### createSvpWalletConfig
254
155
 
255
- 如需在同一个插件中加入应用级 class,可组合 `uiComponents`:
156
+ 创建 SDK 默认 Wagmi 配置:
256
157
 
257
158
  ```ts
258
- import plugin from 'tailwindcss/plugin'
259
- import { uiComponents } from '@svp-chain-sdk/ui/tailwind'
260
-
261
- const appUi = plugin(({ addComponents }) => {
262
- addComponents(uiComponents)
263
- addComponents({
264
- '.app-toolbar-button': {
265
- padding: '0.375rem 0.75rem',
266
- },
267
- })
159
+ const config = createSvpWalletConfig({
160
+ projectId: walletConnectProjectId,
161
+ appName: 'SVP App',
268
162
  })
269
-
270
- export default {
271
- plugins: [appUi],
272
- }
273
163
  ```
274
164
 
275
- 只想明确继承按钮配置时,也可以把上例中的 `uiComponents` 换成 `uiButtonComponents`。
165
+ | 参数 | 类型 | 默认值 | 说明 |
166
+ | --- | --- | --- | --- |
167
+ | `projectId` | `string` | 必填 | WalletConnect Project ID |
168
+ | `appName` | `string` | `'SVP App'` | 应用名称 |
276
169
 
277
- 默认插件与导出的配置对象来自同一份组件定义。请在以下两种方式中二选一,避免重复注册:
170
+ 默认包含 Sepolia、SVP Testnet、Arbitrum Sepolia,以及 SVP Wallet、MetaMask、OKX、Rainbow、WalletConnect、Base Account 和 Safe。
278
171
 
279
- 1. `plugins: [svpUi]`;或
280
- 2. 自定义 plugin 中 `addComponents(uiComponents)`。
172
+ ### 钱包工具与常量
281
173
 
282
- 注意:第二种方式只加入组件规则,不会自动加入默认插件通过 `addBase` 设置的 `--svp-ui-brand`。由于现有按钮规则未使用该变量,这不影响当前按钮样式;如果应用依赖该变量,应自行在 CSS 或自定义 plugin 中声明。
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 地址 |
283
183
 
284
- ## 9. 常见问题
184
+ ### FeedbackWidget
285
185
 
286
- ### class 写了但样式不生效
186
+ 页面右侧垂直居中的悬浮入口,点击后在新标签页打开内置 Google Form。
287
187
 
288
- 依次检查:
188
+ ```tsx
189
+ <FeedbackWidget />
190
+ <FeedbackWidget className="my-feedback" />
191
+ ```
289
192
 
290
- 1. 已安装并能解析 `@svp-chain-sdk/ui/tailwind`。
291
- 2. provider 已加入实际生效的 Tailwind 配置,且没有同时使用默认插件和自定义重复注册。
292
- 3. Tailwind 构建流程已运行,产物 CSS 已被页面加载。
293
- 4. 基础 class 与变体 class 已组合,例如 `ui-button ui-button-primary`。
294
- 5. 消费项目的 CSS 是否以更高优先级覆盖了规则。
295
- 6. 若不使用 provider,可改为导入 `@svp-chain-sdk/ui/styles.css`。它是包构建时从当前 Tailwind v4 样式入口生成并复制的 CSS,但不是 provider 按钮组件规则的替代品;不要假定导入它会生成 `.ui-button`、`.ui-button-primary` 或 `.ui-button-danger`。
193
+ #### FeedbackWidgetProps
296
194
 
297
- ### 出现 CommonJS / `require()` 错误
195
+ | 参数 | 类型 | 默认值 | 说明 |
196
+ | --- | --- | --- | --- |
197
+ | `className` | `string` | 无 | 附加 class |
298
198
 
299
- 包的 `package.json` 声明了 `"type": "module"`,根入口和 `./tailwind` export 只有 `import` 条件,没有 CommonJS `require` 条件。请使用 ESM:
199
+ 内置地址:`https://forms.gle/6semmo55DSLtcbnw7`。链接使用 `target="_blank"` `rel="noopener noreferrer"`。
300
200
 
301
- ```ts
302
- import svpUi from '@svp-chain-sdk/ui/tailwind'
303
- ```
201
+ ### NoticeMarquee
304
202
 
305
- 不要使用:
203
+ 顶部居中的高层级通知浮层,默认距顶部 `100px`。默认读取 SDK 内置 IPFS JSON,根据浏览器语言选择文案,并每 5 分钟静默刷新。用户可以点击“已知晓”或关闭按钮。
306
204
 
307
- ```js
308
- const svpUi = require('@svp-chain-sdk/ui/tailwind')
205
+ - **已知晓**:记录当前完整公告快照,本轮公告不再显示;远程公告内容发生变化后会再次显示。
206
+ - **关闭**:只关闭当前页面实例,不写入 localStorage;刷新页面后仍会再次显示。
207
+
208
+ ```tsx
209
+ <NoticeMarquee />
210
+
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
+ />
309
219
  ```
310
220
 
311
- 如果工具默认把 `tailwind.config` 当作 CommonJS,请切换到它支持的 ESM 配置形式;具体文件名和配置取决于消费项目的构建工具。
221
+ 远程 JSON:
312
222
 
313
- ### 可以把 class 放在 `<div>` 上吗?
223
+ ```json
224
+ {
225
+ "en": "English notice",
226
+ "zh": "中文通知",
227
+ "fr": "Notification française"
228
+ }
229
+ ```
314
230
 
315
- 视觉上可以,但 class 不会让 `<div>` 自动获得按钮语义、键盘操作或原生禁用行为。优先使用原生 `<button type="button">`。
231
+ 中文读取 `zh`,法语读取 `fr`,其他语言读取 `en`;缺失时回退到 `en`,再回退到第一个非空字符串。内容按纯文本渲染。组件通过 localStorage 记录完整公告快照,相同公告不重复播放。
316
232
 
317
- 若业务确实必须使用 `<div>`,至少需要自行完整实现 `role="button"`、`tabindex="0"`、Enter/Space 键盘触发、禁用语义与事件拦截。尤其要注意 `.ui-button:disabled` 不会匹配 `<div aria-disabled="true">`,provider 也不会替你实现这些交互。能使用原生按钮时不要用 `<div>` 模拟。
233
+ #### NoticeMarqueeProps
318
234
 
319
- ## 10. 版本升级与发布
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 |
320
243
 
321
- 以下命令在 `packages/ui` 目录执行,默认发布 patch 版本:
244
+ 桌面端默认宽度最大 `42rem`、距顶部 `100px`、层级 `2147483647`,动画周期 `32s`,hover 时暂停。560px 以下改为距安全区顶部 16px 的自适应卡片并停止滚动,以保证长文本可读。动画周期可以通过 CSS 调整:
322
245
 
323
- ```sh
324
- npm run release
325
- npm run release:patch
326
- npm run release:minor
327
- npm run release:major
246
+ ```css
247
+ :root {
248
+ --ui-notice-marquee-duration: 24s;
249
+ }
328
250
  ```
329
251
 
330
- 发布前必须先完成 `npm login`,并确认当前账号有权发布 `@svp-chain-sdk/ui`。命令按顺序执行:
252
+ | 常量 | 说明 |
253
+ | --- | --- |
254
+ | `DEFAULT_NOTICE_URL` | 默认通知 JSON 地址 |
255
+ | `DEFAULT_NOTICE_STORAGE_KEY` | 默认 localStorage key |
256
+ | `DEFAULT_NOTICE_REFRESH_INTERVAL_MS` | 默认刷新间隔 `5 * 60 * 1000` |
331
257
 
332
- 1. `npm run build`、`npm run typecheck`、`npm run test`;任一失败都会立即停止,版本不会被修改,也不会发布。
333
- 2. 通过后使用 `npm version <type> --no-git-tag-version` 更新 `package.json`,不创建 Git commit/tag。
334
- 3. 使用 `pnpm install --lockfile-only --ignore-scripts` 同步仓库的 `pnpm-lock.yaml`,再执行 `npm publish --access public`。
258
+ ### cn
335
259
 
336
- 首次发布或正式发布前,建议先运行完整的安全演练:
260
+ 合并条件 class 并处理 Tailwind class 冲突:
337
261
 
338
- ```sh
339
- npm run release -- --dry-run
340
- npm run release:minor -- --dry-run
262
+ ```ts
263
+ const className = cn('px-4', active && 'bg-primary', disabled && 'opacity-50')
341
264
  ```
342
265
 
343
- `--dry-run` 仍会运行 build、typecheck、test,并执行 npm 的发布包校验,但不会升级版本、写入锁文件或上传 registry。它不会验证 npm 登录权限或版本是否已被占用。正式发布前请确认 package version 尚未存在于 npm;失败时脚本会输出失败步骤和退出码,不输出 npm 配置或凭据。版本升级成功后,若锁文件同步或 npm 发布失败,版本文件可能已改变,需要人工检查后再重试;脚本不会自动回滚或覆盖工作区改动。
344
-
345
- `prepublishOnly` 保留为 npm 的独立发布保护,会再次运行质量检查;`release` 脚本不依赖 Git 提交或 tag。
266
+ ```ts
267
+ cn(...inputs: ClassValue[]): string
268
+ ```
346
269
 
347
- ## 11. 当前公开入口速查
270
+ ### Tailwind Provider 导出
348
271
 
349
- 以 `packages/ui/package.json` 当前的 `exports` 为准:
272
+ ```ts
273
+ import svpUi, {
274
+ uiButtonComponents,
275
+ uiNoticeMarqueeComponents,
276
+ uiComponents,
277
+ } from '@svp-chain-sdk/ui/tailwind'
278
+ ```
350
279
 
351
- | 导入路径 | 当前内容 |
280
+ | 导出 | 说明 |
352
281
  | --- | --- |
353
- | `@svp-chain-sdk/ui/tailwind` | 默认 Tailwind plugin;具名 `uiButtonComponents`、`uiComponents` |
354
- | `@svp-chain-sdk/ui` | 可选 React `Button`、`buttonVariants`、`ButtonProps` 和 `cn` |
355
- | `@svp-chain-sdk/ui/styles.css` | 包构建产出的 Tailwind v4 CSS 样式入口;当前不包含 provider 的 `.ui-button*` 规则 |
356
-
357
- 所有 JavaScript 入口均按 ESM 使用。公开 API 之外的源码路径不属于 package exports,不应从消费项目直接导入。
282
+ | `svpUi` | 默认 Tailwind plugin |
283
+ | `uiButtonComponents` | 按钮 class 配置 |
284
+ | `uiNoticeMarqueeComponents` | 走马灯 class 与动画配置 |
285
+ | `uiComponents` | 全部 provider 配置 |
@@ -0,0 +1,2 @@
1
+ export { Button, buttonVariants } from './button';
2
+ export type { ButtonProps } from './button';
@@ -0,0 +1,4 @@
1
+ export interface FeedbackWidgetProps {
2
+ className?: string;
3
+ }
4
+ export declare function FeedbackWidget({ className }?: FeedbackWidgetProps): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { FeedbackWidget } from './feedback-widget';
2
+ export type { FeedbackWidgetProps } from './feedback-widget';
@@ -0,0 +1,6 @@
1
+ export { Button, buttonVariants } from './button';
2
+ export type { ButtonProps } from './button';
3
+ export { FeedbackWidget } from './feedback-widget';
4
+ export type { FeedbackWidgetProps } from './feedback-widget';
5
+ export { DEFAULT_NOTICE_REFRESH_INTERVAL_MS, DEFAULT_NOTICE_STORAGE_KEY, DEFAULT_NOTICE_URL, NoticeMarquee, } from './notice-marquee';
6
+ export type { NoticeMarqueeProps } from './notice-marquee';
@@ -0,0 +1,2 @@
1
+ export { DEFAULT_NOTICE_REFRESH_INTERVAL_MS, DEFAULT_NOTICE_STORAGE_KEY, DEFAULT_NOTICE_URL, NoticeMarquee, } from './notice-marquee';
2
+ export type { NoticeMarqueeProps } from './notice-marquee';
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ export declare const DEFAULT_NOTICE_URL = "https://moccasin-glad-tyrannosaurus-244.mypinata.cloud/ipfs/bafkreiavwd7xwacprggfzpdcicluvv4tzdxdfzj6brlzayxsk64upezdwa";
3
+ export declare const DEFAULT_NOTICE_STORAGE_KEY = "@svp-chain-sdk/ui:notice-marquee";
4
+ export declare const DEFAULT_NOTICE_REFRESH_INTERVAL_MS: number;
5
+ export type NoticeMarqueeProps = {
6
+ /** Optional override for the SDK default multilingual JSON URL. */
7
+ url?: string;
8
+ /** Optional override for the localStorage key used to remember acknowledged content. */
9
+ storageKey?: string;
10
+ /** Optional override for the default five-minute silent refresh interval. */
11
+ refreshIntervalMs?: number;
12
+ acknowledgeLabel?: string;
13
+ closeLabel?: string;
14
+ className?: string;
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.
19
+ */
20
+ export declare function NoticeMarquee({ url, storageKey, refreshIntervalMs, acknowledgeLabel, closeLabel, className, }?: NoticeMarqueeProps): React.JSX.Element | null;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { Button, buttonVariants } from './button';
2
- export type { ButtonProps } from './button';
3
- export { cn } from './utils';
1
+ export { Button, buttonVariants, DEFAULT_NOTICE_REFRESH_INTERVAL_MS, DEFAULT_NOTICE_STORAGE_KEY, DEFAULT_NOTICE_URL, FeedbackWidget, NoticeMarquee, } from './components';
2
+ export type { ButtonProps, FeedbackWidgetProps, NoticeMarqueeProps, } from './components';
3
+ export { cn } from './lib/utils';
4
4
  export { ConnectWalletButton, createSvpWalletConfig, resolveSvpProvider, resolveSvpProviderForConnection, SVP_WALLET_DOWNLOAD_URL, svpTestnet, svpWallet, SvpWalletProvider, walletDefaults, walletTheme, } from './wallet';
5
5
  export type { ConnectWalletButtonProps, ConnectWalletLabels, CreateSvpWalletConfigOptions, SvpWalletProviderProps, SvpWalletDefaults, } from './wallet';