@hopgoldy/cube-ui 0.1.0 → 0.2.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/README.md CHANGED
@@ -82,6 +82,27 @@ export const LoginPage = () => (
82
82
  );
83
83
  ```
84
84
 
85
- `CubePage` is the single page-level container every page renders: it lays out scrollable content and an optional mobile-only action bar, and lets the page override `CubeApp`'s header-left slot via `desktopHeaderLeft` for as long as it stays mounted. `ActionIcon` and `ActionButton` are the shared mobile action-bar primitives, matching the pattern already used in cube-xxx apps.
85
+ `CubePage` is the single page-level container every page renders: it lays out scrollable content and an optional mobile-only action bar, and lets the page override `CubeApp`'s header-left slot via `desktopHeaderLeft` for as long as it stays mounted. `ActionIcon` and `ActionButton` are the shared mobile action-bar primitives, matching the pattern already used in cube-xxx apps. `ActionSearch` is the matching search field that fills the remaining action-bar width.
86
+
87
+ `CubeSearchPage` is the shared search-page shell: desktop `Input.Search` plus optional filters, a mobile action bar (back, optional filter drawer, search), and pending / loading / empty states via `EmptyTip`. Apps pass result rows as children and filter UI (for example `ColorList`) through the `filters` slot — item cards and data fetching stay in the app.
88
+
89
+ ```tsx
90
+ import { ColorList, CubeSearchPage } from "@hopgoldy/cube-ui";
91
+
92
+ <CubeSearchPage
93
+ keyword={keyword}
94
+ onSearch={setKeyword}
95
+ onBack={() => navigate(-1)}
96
+ desktopHeaderLeft="搜索凭证"
97
+ pending={!keyword && colors.length === 0}
98
+ loading={isSearching}
99
+ empty={items.length === 0}
100
+ emptyTitle="没有找到相关凭证"
101
+ filters={<ColorList value={colors[0] || ""} onChange={onSelectColor} />}
102
+ mobileFilterTitle="凭证筛选"
103
+ >
104
+ {items.map(renderItem)}
105
+ </CubeSearchPage>
106
+ ```
86
107
 
87
108
  This package is intentionally UI-only. It does not depend on routers, HTTP clients, application stores, or authentication logic.
package/dist/index.css CHANGED
@@ -9,8 +9,8 @@
9
9
  --cube-dark-surface-color: #141414;
10
10
  }
11
11
 
12
- /* src/app-header/app-header.module.css */
13
- .root {
12
+ /* src/app-header/app-header.css */
13
+ .cube-app-header {
14
14
  display: flex;
15
15
  align-items: center;
16
16
  justify-content: space-between;
@@ -27,19 +27,19 @@
27
27
  background-color 200ms ease,
28
28
  border-color 200ms ease;
29
29
  }
30
- :global(.dark) .root,
31
- :global([data-theme=dark]) .root {
30
+ .dark .cube-app-header,
31
+ [data-theme=dark] .cube-app-header {
32
32
  background: var(--cube-dark-surface-color, #141414);
33
33
  border-bottom-color: var(--cube-dark-border-color, #374151);
34
34
  }
35
- .leading {
35
+ .cube-app-header-leading {
36
36
  display: flex;
37
37
  flex: 1 1 auto;
38
38
  align-items: center;
39
39
  min-width: 0;
40
40
  overflow: hidden;
41
41
  }
42
- .toggle {
42
+ .cube-app-header-toggle {
43
43
  display: inline-flex;
44
44
  flex: 0 0 auto;
45
45
  align-items: center;
@@ -53,18 +53,18 @@
53
53
  background: transparent;
54
54
  border: 0;
55
55
  }
56
- .toggle:focus-visible {
56
+ .cube-app-header-toggle:focus-visible {
57
57
  outline: 2px solid #1677ff;
58
58
  outline-offset: 3px;
59
59
  border-radius: 2px;
60
60
  }
61
- .title {
61
+ .cube-app-header-title {
62
62
  min-width: 0;
63
63
  overflow: hidden;
64
64
  text-overflow: ellipsis;
65
65
  white-space: nowrap;
66
66
  }
67
- .actions {
67
+ .cube-app-header-actions {
68
68
  display: flex;
69
69
  flex: 0 0 auto;
70
70
  align-items: center;
@@ -72,8 +72,8 @@
72
72
  margin-left: 0.5rem;
73
73
  }
74
74
 
75
- /* src/account-menu/account-menu.module.css */
76
- .trigger {
75
+ /* src/account-menu/account-menu.css */
76
+ .cube-account-trigger {
77
77
  display: inline-flex;
78
78
  align-items: center;
79
79
  justify-content: center;
@@ -87,134 +87,134 @@
87
87
  background: transparent;
88
88
  border: 0;
89
89
  }
90
- .trigger:focus-visible {
90
+ .cube-account-trigger:focus-visible {
91
91
  outline: 2px solid #1677ff;
92
92
  outline-offset: 3px;
93
93
  border-radius: 50%;
94
94
  }
95
- .menu {
95
+ .cube-account-menu {
96
96
  width: 16rem;
97
97
  max-width: calc(100vw - 2rem);
98
98
  }
99
- .stats {
99
+ .cube-account-menu-stats {
100
100
  display: flex;
101
101
  justify-content: space-around;
102
102
  gap: 1rem;
103
103
  margin-bottom: 1rem;
104
104
  }
105
- .items {
105
+ .cube-account-menu-items {
106
106
  display: flex;
107
107
  flex-direction: column;
108
108
  gap: 0.5rem;
109
109
  }
110
- .footer {
110
+ .cube-account-menu-footer {
111
111
  margin-top: 0.5rem;
112
112
  }
113
113
 
114
- /* src/about-dialog/about-dialog.module.css */
115
- .body {
114
+ /* src/about-dialog/about-dialog.css */
115
+ .cube-about-body {
116
116
  margin-bottom: 1rem;
117
117
  }
118
- .description {
118
+ .cube-about-description {
119
119
  margin: 1rem 0 0.5rem;
120
120
  font-size: 1rem;
121
121
  line-height: 1.5;
122
122
  }
123
- .item {
123
+ .cube-about-item {
124
124
  padding: 0.5rem;
125
125
  color: #6b7280;
126
126
  background: #f3f4f6;
127
127
  border-radius: 0.375rem;
128
128
  }
129
- :global(.dark) .item,
130
- :global([data-theme=dark]) .item {
129
+ .dark .cube-about-item,
130
+ [data-theme=dark] .cube-about-item {
131
131
  color: #e5e7eb;
132
132
  background: #262626;
133
133
  }
134
- .itemLabel {
134
+ .cube-about-item-label {
135
135
  color: inherit;
136
136
  white-space: nowrap;
137
137
  }
138
- .itemValue {
138
+ .cube-about-item-value {
139
139
  min-width: 0;
140
140
  overflow: hidden;
141
141
  text-align: right;
142
142
  text-overflow: ellipsis;
143
143
  white-space: nowrap;
144
144
  }
145
- .link {
145
+ .cube-about-link {
146
146
  color: inherit;
147
147
  text-decoration: none;
148
148
  }
149
- .poweredBy {
149
+ .cube-about-powered-by {
150
150
  color: #6b7280;
151
151
  }
152
- :global(.dark) .poweredBy,
153
- :global([data-theme=dark]) .poweredBy {
152
+ .dark .cube-about-powered-by,
153
+ [data-theme=dark] .cube-about-powered-by {
154
154
  color: #e5e7eb;
155
155
  }
156
156
 
157
- /* src/cube-app/cube-app.module.css */
158
- .root {
157
+ /* src/cube-app/cube-app.css */
158
+ .cube-app-root {
159
159
  display: flex;
160
160
  width: 100%;
161
161
  height: 100%;
162
162
  overflow: hidden;
163
163
  }
164
- .sidebar {
164
+ .cube-app-sidebar {
165
165
  display: flex;
166
166
  flex-direction: column;
167
167
  flex-shrink: 0;
168
168
  overflow: hidden;
169
169
  transition: width 200ms ease;
170
170
  }
171
- .sidebarTop,
172
- .sidebarBottom {
171
+ .cube-app-sidebar-top,
172
+ .cube-app-sidebar-bottom {
173
173
  flex-shrink: 0;
174
174
  }
175
- .sidebarList {
175
+ .cube-app-sidebar-list {
176
176
  flex: 1 1 auto;
177
177
  min-height: 0;
178
178
  overflow-y: auto;
179
179
  }
180
- .desktopArea {
180
+ .cube-app-desktop-area {
181
181
  flex-grow: 1;
182
182
  min-width: 0;
183
183
  height: 100%;
184
184
  overflow: hidden;
185
185
  transition: width 200ms ease;
186
186
  }
187
- .content {
187
+ .cube-app-content {
188
188
  height: calc(100% - var(--cube-header-height, 3rem) - 1px);
189
189
  overflow-y: auto;
190
190
  }
191
- .searchButton {
191
+ .cube-app-search-button {
192
192
  width: 15rem;
193
193
  }
194
- .mobileRoot {
194
+ .cube-app-mobile-root {
195
195
  width: 100vw;
196
196
  height: 100%;
197
197
  overflow: hidden;
198
198
  }
199
- .mobileContent {
199
+ .cube-app-mobile-content {
200
200
  width: 100%;
201
201
  height: 100%;
202
202
  overflow-y: auto;
203
203
  }
204
204
 
205
- /* src/mobile-account-sheet/mobile-account-sheet.module.css */
206
- .card {
205
+ /* src/mobile-account-sheet/mobile-account-sheet.css */
206
+ .cube-sheet-card {
207
207
  padding: 0.5rem 0.75rem;
208
208
  background: var(--cube-surface-color, #fff);
209
209
  border: 1px solid var(--cube-border-color, #d1d5db);
210
210
  border-radius: 0.5rem;
211
211
  }
212
- :global(.dark) .card,
213
- :global([data-theme=dark]) .card {
212
+ .dark .cube-sheet-card,
213
+ [data-theme=dark] .cube-sheet-card {
214
214
  background: var(--cube-dark-surface-color, #141414);
215
215
  border-color: var(--cube-dark-border-color, #374151);
216
216
  }
217
- .cell {
217
+ .cube-sheet-cell {
218
218
  display: flex;
219
219
  align-items: center;
220
220
  justify-content: space-between;
@@ -227,50 +227,50 @@
227
227
  background: transparent;
228
228
  border: 0;
229
229
  }
230
- .splitLine {
230
+ .cube-sheet-split-line {
231
231
  height: 1px;
232
232
  margin: 0.25rem 0;
233
233
  background: var(--cube-border-color, #d1d5db);
234
234
  }
235
- :global(.dark) .splitLine,
236
- :global([data-theme=dark]) .splitLine {
235
+ .dark .cube-sheet-split-line,
236
+ [data-theme=dark] .cube-sheet-split-line {
237
237
  background: var(--cube-dark-border-color, #374151);
238
238
  }
239
239
 
240
- /* src/loading/loading.module.css */
241
- .pageLoading {
240
+ /* src/loading/loading.css */
241
+ .cube-page-loading {
242
242
  width: 100%;
243
243
  height: 100%;
244
244
  }
245
- .delayedLoading {
245
+ .cube-delayed-loading {
246
246
  display: flex;
247
247
  align-items: center;
248
248
  justify-content: center;
249
249
  width: 100%;
250
250
  margin: 1.5rem 0;
251
251
  }
252
- :global(.dark) .delayedLoading,
253
- :global([data-theme=dark]) .delayedLoading {
252
+ .dark .cube-delayed-loading,
253
+ [data-theme=dark] .cube-delayed-loading {
254
254
  color: #9ca3af;
255
255
  }
256
256
 
257
- /* src/page/page.module.css */
258
- .container {
257
+ /* src/page/page.css */
258
+ .cube-page-container {
259
259
  width: 100%;
260
260
  height: 100%;
261
261
  overflow: hidden;
262
262
  }
263
- .content {
263
+ .cube-page-content {
264
264
  position: relative;
265
265
  height: 100%;
266
266
  overflow-y: auto;
267
267
  }
268
268
  @media (max-width: 767px) {
269
- .content {
269
+ .cube-page-content {
270
270
  height: calc(100% - var(--cube-mobile-action-height, 40px) - 1rem);
271
271
  }
272
272
  }
273
- .actionBar {
273
+ .cube-page-action-bar {
274
274
  display: flex;
275
275
  flex-direction: row;
276
276
  align-items: center;
@@ -278,7 +278,77 @@
278
278
  height: var(--cube-mobile-action-height, 40px);
279
279
  padding: 0.5rem;
280
280
  }
281
- .actionIcon {
281
+ .cube-page-action-icon {
282
282
  flex-shrink: 0;
283
283
  }
284
+ .cube-page-action-search {
285
+ flex: 1;
286
+ min-width: 0;
287
+ }
288
+
289
+ /* src/empty-tip/empty-tip.css */
290
+ .cube-empty-tip-title {
291
+ font-weight: 700;
292
+ font-size: 1rem;
293
+ }
294
+ .cube-empty-tip-subtitle {
295
+ color: #9ca3af;
296
+ }
297
+
298
+ /* src/color-list/color-list.css */
299
+ .cube-color-dot {
300
+ width: 1.5rem;
301
+ height: 1.5rem;
302
+ padding: 0;
303
+ border: none;
304
+ border-radius: 9999px;
305
+ cursor: pointer;
306
+ transition: box-shadow 0.15s ease;
307
+ }
308
+ .cube-color-dot:hover {
309
+ box-shadow: 0 0 0 4px #d1d5db;
310
+ }
311
+ html.dark .cube-color-dot:hover,
312
+ [data-theme=dark] .cube-color-dot:hover {
313
+ box-shadow: 0 0 0 4px #737373;
314
+ }
315
+ .cube-color-dot-selected {
316
+ box-shadow: 0 0 0 4px #9ca3af;
317
+ }
318
+ .cube-color-dot-selected:hover {
319
+ box-shadow: 0 0 0 4px #9ca3af;
320
+ }
321
+ html.dark .cube-color-dot-selected,
322
+ [data-theme=dark] .cube-color-dot-selected,
323
+ html.dark .cube-color-dot-selected:hover,
324
+ [data-theme=dark] .cube-color-dot-selected:hover {
325
+ box-shadow: 0 0 0 4px #4b5563;
326
+ }
327
+ .cube-color-dot-clear {
328
+ border: 2px solid #ef4444;
329
+ position: relative;
330
+ overflow: hidden;
331
+ background-color: transparent;
332
+ }
333
+ .cube-color-dot-clear::after {
334
+ content: "";
335
+ position: absolute;
336
+ left: -1px;
337
+ top: 10px;
338
+ width: 25px;
339
+ height: 2px;
340
+ background: #ef4444;
341
+ transform: rotate(45deg);
342
+ }
343
+
344
+ /* src/search-page/search-page.css */
345
+ .cube-search-page {
346
+ width: 100%;
347
+ box-sizing: border-box;
348
+ padding: 1rem;
349
+ }
350
+ .cube-search-page-input,
351
+ .cube-search-page-results {
352
+ width: 100%;
353
+ }
284
354
  /*# sourceMappingURL=index.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/styles.css","../src/app-header/app-header.module.css","../src/account-menu/account-menu.module.css","../src/about-dialog/about-dialog.module.css","../src/cube-app/cube-app.module.css","../src/mobile-account-sheet/mobile-account-sheet.module.css","../src/loading/loading.module.css","../src/page/page.module.css"],"sourcesContent":[":root {\n --cube-header-height: 3rem;\n --cube-sidebar-width: 15rem;\n --cube-mobile-action-height: 40px;\n --cube-border-color: #d1d5db;\n --cube-dark-border-color: #374151;\n --cube-surface-color: #ffffff;\n --cube-dark-surface-color: #141414;\n}\n",".root {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: var(--cube-header-height, 3rem);\n padding: 0.5rem 1rem;\n overflow: hidden;\n box-sizing: border-box;\n color: inherit;\n background: var(--cube-surface-color, #fff);\n border-bottom: 1px solid var(--cube-border-color, #d1d5db);\n transition: color 200ms ease, background-color 200ms ease,\n border-color 200ms ease;\n}\n\n:global(.dark) .root,\n:global([data-theme=\"dark\"]) .root {\n background: var(--cube-dark-surface-color, #141414);\n border-bottom-color: var(--cube-dark-border-color, #374151);\n}\n\n.leading {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n}\n\n.toggle {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n padding: 0;\n margin: 0 1rem 0 0;\n font: inherit;\n font-size: 1.25rem;\n color: inherit;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.toggle:focus-visible {\n outline: 2px solid #1677ff;\n outline-offset: 3px;\n border-radius: 2px;\n}\n\n.title {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.actions {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 0.5rem;\n margin-left: 0.5rem;\n}\n",".trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n margin: 0;\n font: inherit;\n font-size: 1.25rem;\n line-height: 1;\n color: inherit;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.trigger:focus-visible {\n outline: 2px solid #1677ff;\n outline-offset: 3px;\n border-radius: 50%;\n}\n\n.menu {\n width: 16rem;\n max-width: calc(100vw - 2rem);\n}\n\n.stats {\n display: flex;\n justify-content: space-around;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.items {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.footer {\n margin-top: 0.5rem;\n}\n",".body {\n margin-bottom: 1rem;\n}\n\n.description {\n margin: 1rem 0 0.5rem;\n font-size: 1rem;\n line-height: 1.5;\n}\n\n.item {\n padding: 0.5rem;\n color: #6b7280;\n background: #f3f4f6;\n border-radius: 0.375rem;\n}\n\n:global(.dark) .item,\n:global([data-theme=\"dark\"]) .item {\n color: #e5e7eb;\n background: #262626;\n}\n\n.itemLabel {\n color: inherit;\n white-space: nowrap;\n}\n\n.itemValue {\n min-width: 0;\n overflow: hidden;\n text-align: right;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.link {\n color: inherit;\n text-decoration: none;\n}\n\n.poweredBy {\n color: #6b7280;\n}\n\n:global(.dark) .poweredBy,\n:global([data-theme=\"dark\"]) .poweredBy {\n color: #e5e7eb;\n}\n",".root {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.sidebar {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n overflow: hidden;\n transition: width 200ms ease;\n}\n\n.sidebarTop,\n.sidebarBottom {\n flex-shrink: 0;\n}\n\n.sidebarList {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n}\n\n.desktopArea {\n flex-grow: 1;\n min-width: 0;\n height: 100%;\n overflow: hidden;\n transition: width 200ms ease;\n}\n\n.content {\n height: calc(100% - var(--cube-header-height, 3rem) - 1px);\n overflow-y: auto;\n}\n\n.searchButton {\n width: 15rem;\n}\n\n.mobileRoot {\n width: 100vw;\n height: 100%;\n overflow: hidden;\n}\n\n.mobileContent {\n width: 100%;\n height: 100%;\n overflow-y: auto;\n}\n",".card {\n padding: 0.5rem 0.75rem;\n background: var(--cube-surface-color, #fff);\n border: 1px solid var(--cube-border-color, #d1d5db);\n border-radius: 0.5rem;\n}\n\n:global(.dark) .card,\n:global([data-theme=\"dark\"]) .card {\n background: var(--cube-dark-surface-color, #141414);\n border-color: var(--cube-dark-border-color, #374151);\n}\n\n.cell {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 0.375rem 0;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.splitLine {\n height: 1px;\n margin: 0.25rem 0;\n background: var(--cube-border-color, #d1d5db);\n}\n\n:global(.dark) .splitLine,\n:global([data-theme=\"dark\"]) .splitLine {\n background: var(--cube-dark-border-color, #374151);\n}\n",".pageLoading {\n width: 100%;\n height: 100%;\n}\n\n.delayedLoading {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n margin: 1.5rem 0;\n}\n\n:global(.dark) .delayedLoading,\n:global([data-theme=\"dark\"]) .delayedLoading {\n color: #9ca3af;\n}\n",".container {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.content {\n position: relative;\n height: 100%;\n overflow-y: auto;\n}\n\n@media (max-width: 767px) {\n .content {\n height: calc(100% - var(--cube-mobile-action-height, 40px) - 1rem);\n }\n}\n\n.actionBar {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 0.5rem;\n height: var(--cube-mobile-action-height, 40px);\n padding: 0.5rem;\n}\n\n.actionIcon {\n flex-shrink: 0;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/styles.css","../src/app-header/app-header.css","../src/account-menu/account-menu.css","../src/about-dialog/about-dialog.css","../src/cube-app/cube-app.css","../src/mobile-account-sheet/mobile-account-sheet.css","../src/loading/loading.css","../src/page/page.css","../src/empty-tip/empty-tip.css","../src/color-list/color-list.css","../src/search-page/search-page.css"],"sourcesContent":[":root {\n --cube-header-height: 3rem;\n --cube-sidebar-width: 15rem;\n --cube-mobile-action-height: 40px;\n --cube-border-color: #d1d5db;\n --cube-dark-border-color: #374151;\n --cube-surface-color: #ffffff;\n --cube-dark-surface-color: #141414;\n}\n",".cube-app-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: var(--cube-header-height, 3rem);\n padding: 0.5rem 1rem;\n overflow: hidden;\n box-sizing: border-box;\n color: inherit;\n background: var(--cube-surface-color, #fff);\n border-bottom: 1px solid var(--cube-border-color, #d1d5db);\n transition: color 200ms ease, background-color 200ms ease,\n border-color 200ms ease;\n}\n\n.dark .cube-app-header,\n[data-theme=\"dark\"] .cube-app-header {\n background: var(--cube-dark-surface-color, #141414);\n border-bottom-color: var(--cube-dark-border-color, #374151);\n}\n\n.cube-app-header-leading {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n}\n\n.cube-app-header-toggle {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n padding: 0;\n margin: 0 1rem 0 0;\n font: inherit;\n font-size: 1.25rem;\n color: inherit;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.cube-app-header-toggle:focus-visible {\n outline: 2px solid #1677ff;\n outline-offset: 3px;\n border-radius: 2px;\n}\n\n.cube-app-header-title {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.cube-app-header-actions {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 0.5rem;\n margin-left: 0.5rem;\n}\n",".cube-account-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n margin: 0;\n font: inherit;\n font-size: 1.25rem;\n line-height: 1;\n color: inherit;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.cube-account-trigger:focus-visible {\n outline: 2px solid #1677ff;\n outline-offset: 3px;\n border-radius: 50%;\n}\n\n.cube-account-menu {\n width: 16rem;\n max-width: calc(100vw - 2rem);\n}\n\n.cube-account-menu-stats {\n display: flex;\n justify-content: space-around;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.cube-account-menu-items {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.cube-account-menu-footer {\n margin-top: 0.5rem;\n}\n",".cube-about-body {\n margin-bottom: 1rem;\n}\n\n.cube-about-description {\n margin: 1rem 0 0.5rem;\n font-size: 1rem;\n line-height: 1.5;\n}\n\n.cube-about-item {\n padding: 0.5rem;\n color: #6b7280;\n background: #f3f4f6;\n border-radius: 0.375rem;\n}\n\n.dark .cube-about-item,\n[data-theme=\"dark\"] .cube-about-item {\n color: #e5e7eb;\n background: #262626;\n}\n\n.cube-about-item-label {\n color: inherit;\n white-space: nowrap;\n}\n\n.cube-about-item-value {\n min-width: 0;\n overflow: hidden;\n text-align: right;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.cube-about-link {\n color: inherit;\n text-decoration: none;\n}\n\n.cube-about-powered-by {\n color: #6b7280;\n}\n\n.dark .cube-about-powered-by,\n[data-theme=\"dark\"] .cube-about-powered-by {\n color: #e5e7eb;\n}\n",".cube-app-root {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.cube-app-sidebar {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n overflow: hidden;\n transition: width 200ms ease;\n}\n\n.cube-app-sidebar-top,\n.cube-app-sidebar-bottom {\n flex-shrink: 0;\n}\n\n.cube-app-sidebar-list {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n}\n\n.cube-app-desktop-area {\n flex-grow: 1;\n min-width: 0;\n height: 100%;\n overflow: hidden;\n transition: width 200ms ease;\n}\n\n.cube-app-content {\n height: calc(100% - var(--cube-header-height, 3rem) - 1px);\n overflow-y: auto;\n}\n\n.cube-app-search-button {\n width: 15rem;\n}\n\n.cube-app-mobile-root {\n width: 100vw;\n height: 100%;\n overflow: hidden;\n}\n\n.cube-app-mobile-content {\n width: 100%;\n height: 100%;\n overflow-y: auto;\n}\n",".cube-sheet-card {\n padding: 0.5rem 0.75rem;\n background: var(--cube-surface-color, #fff);\n border: 1px solid var(--cube-border-color, #d1d5db);\n border-radius: 0.5rem;\n}\n\n.dark .cube-sheet-card,\n[data-theme=\"dark\"] .cube-sheet-card {\n background: var(--cube-dark-surface-color, #141414);\n border-color: var(--cube-dark-border-color, #374151);\n}\n\n.cube-sheet-cell {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 0.375rem 0;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.cube-sheet-split-line {\n height: 1px;\n margin: 0.25rem 0;\n background: var(--cube-border-color, #d1d5db);\n}\n\n.dark .cube-sheet-split-line,\n[data-theme=\"dark\"] .cube-sheet-split-line {\n background: var(--cube-dark-border-color, #374151);\n}\n",".cube-page-loading {\n width: 100%;\n height: 100%;\n}\n\n.cube-delayed-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n margin: 1.5rem 0;\n}\n\n.dark .cube-delayed-loading,\n[data-theme=\"dark\"] .cube-delayed-loading {\n color: #9ca3af;\n}\n",".cube-page-container {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.cube-page-content {\n position: relative;\n height: 100%;\n overflow-y: auto;\n}\n\n@media (max-width: 767px) {\n .cube-page-content {\n height: calc(100% - var(--cube-mobile-action-height, 40px) - 1rem);\n }\n}\n\n.cube-page-action-bar {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 0.5rem;\n height: var(--cube-mobile-action-height, 40px);\n padding: 0.5rem;\n}\n\n.cube-page-action-icon {\n flex-shrink: 0;\n}\n\n.cube-page-action-search {\n flex: 1;\n min-width: 0;\n}\n",".cube-empty-tip-title {\n font-weight: 700;\n font-size: 1rem;\n}\n\n.cube-empty-tip-subtitle {\n color: #9ca3af;\n}\n",".cube-color-dot {\n width: 1.5rem;\n height: 1.5rem;\n padding: 0;\n border: none;\n border-radius: 9999px;\n cursor: pointer;\n transition: box-shadow 0.15s ease;\n}\n\n.cube-color-dot:hover {\n box-shadow: 0 0 0 4px #d1d5db;\n}\n\nhtml.dark .cube-color-dot:hover,\n[data-theme=\"dark\"] .cube-color-dot:hover {\n box-shadow: 0 0 0 4px #737373;\n}\n\n.cube-color-dot-selected {\n box-shadow: 0 0 0 4px #9ca3af;\n}\n\n.cube-color-dot-selected:hover {\n box-shadow: 0 0 0 4px #9ca3af;\n}\n\nhtml.dark .cube-color-dot-selected,\n[data-theme=\"dark\"] .cube-color-dot-selected,\nhtml.dark .cube-color-dot-selected:hover,\n[data-theme=\"dark\"] .cube-color-dot-selected:hover {\n box-shadow: 0 0 0 4px #4b5563;\n}\n\n.cube-color-dot-clear {\n border: 2px solid #ef4444;\n position: relative;\n overflow: hidden;\n background-color: transparent;\n}\n\n.cube-color-dot-clear::after {\n content: \"\";\n position: absolute;\n left: -1px;\n top: 10px;\n width: 25px;\n height: 2px;\n background: #ef4444;\n transform: rotate(45deg);\n}\n",".cube-search-page {\n width: 100%;\n box-sizing: border-box;\n padding: 1rem;\n}\n\n.cube-search-page-input,\n.cube-search-page-results {\n width: 100%;\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { PropsWithChildren, ReactNode, Key, HTMLAttributes } from 'react';
3
- import { ButtonProps } from 'antd';
3
+ import { ButtonProps, FlexProps } from 'antd';
4
+ import { SearchProps } from 'antd/es/input';
4
5
 
5
6
  declare const DEFAULT_MOBILE_BREAKPOINT = 767;
6
7
  interface UseMediaQueryOptions {
@@ -119,10 +120,58 @@ declare const DelayedLoading: ({ tip, delay, className, ...props }: DelayedLoadi
119
120
 
120
121
  declare const ActionIcon: ({ className, size, ...props }: ButtonProps) => react.JSX.Element;
121
122
  declare const ActionButton: ({ children, type, block, size, ...props }: ButtonProps) => react.JSX.Element;
123
+ /** Mobile action-bar search field (fills remaining width). */
124
+ declare const ActionSearch: ({ className, ...props }: SearchProps) => react.JSX.Element;
122
125
  interface CubePageProps extends PropsWithChildren {
123
126
  desktopHeaderLeft?: ReactNode;
124
127
  mobileActionBar?: ReactNode;
125
128
  }
126
129
  declare const CubePage: ({ desktopHeaderLeft, mobileActionBar, children }: CubePageProps) => react.JSX.Element;
127
130
 
128
- export { type AboutAppInfo, type AboutAuthorInfo, type AboutItem, type AccountMenuItem, type AccountMenuStat, ActionButton, ActionIcon, CubeApp, type CubeAppAboutInfo, type CubeAppContextValue, type CubeAppProps, CubeConfigProvider, type CubeConfigProviderProps, CubePage, type CubePageProps, DEFAULT_MOBILE_BREAKPOINT, DelayedLoading, type DelayedLoadingProps, DesktopOnly, MobileAccountSheet, type MobileAccountSheetProps, MobileOnly, PageLoading, type PageLoadingProps, type ResponsiveProps, type UseMediaQueryOptions, useCubeAppContext, useCubeAppHeaderLeft, useIsMobile, useMediaQuery };
131
+ interface EmptyTipProps {
132
+ className?: string;
133
+ title?: ReactNode;
134
+ subTitle?: ReactNode;
135
+ extra?: ReactNode;
136
+ }
137
+ declare const EmptyTip: ({ title, subTitle, extra, className }: EmptyTipProps) => react.JSX.Element;
138
+
139
+ declare const MARK_COLORS_MAP: Record<string, string>;
140
+ declare const MARK_COLORS: readonly ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16"];
141
+ declare const MARK_COLORS_WITH_EMPTY: readonly ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", ""];
142
+ declare const getColorValue: (colorCode: string) => string | undefined;
143
+ interface ColorListProps {
144
+ value?: string;
145
+ onChange?(value: string): void;
146
+ flexProps?: Omit<FlexProps, "children">;
147
+ }
148
+ /** Single-select color dots (includes a clear/empty option), matching Cube search filters. */
149
+ declare const ColorList: ({ value, onChange, flexProps }: ColorListProps) => react.JSX.Element;
150
+
151
+ interface CubeSearchPageProps {
152
+ /** Last committed keyword; used as the search inputs' default value. */
153
+ keyword?: string;
154
+ placeholder?: string;
155
+ searchButtonLabel?: string;
156
+ onSearch(value: string): void;
157
+ onBack(): void;
158
+ desktopHeaderLeft?: ReactNode;
159
+ /** Filter UI (colors, tags, …). Desktop: in the page body. Mobile: in a bottom drawer. */
160
+ filters?: ReactNode;
161
+ mobileFilterTitle?: string;
162
+ mobileFilterIcon?: ReactNode;
163
+ /** True before the first search (no keyword / filters committed). */
164
+ pending?: boolean;
165
+ loading?: boolean;
166
+ /** True after a search that returned no rows. Ignored while pending or loading. */
167
+ empty?: boolean;
168
+ pendingHint?: ReactNode;
169
+ loadingTitle?: ReactNode;
170
+ loadingHint?: ReactNode;
171
+ emptyTitle?: ReactNode;
172
+ emptyHint?: ReactNode;
173
+ children?: ReactNode;
174
+ }
175
+ declare const CubeSearchPage: ({ keyword, placeholder, searchButtonLabel, onSearch, onBack, desktopHeaderLeft, filters, mobileFilterTitle, mobileFilterIcon, pending, loading, empty, pendingHint, loadingTitle, loadingHint, emptyTitle, emptyHint, children, }: CubeSearchPageProps) => react.JSX.Element;
176
+
177
+ export { type AboutAppInfo, type AboutAuthorInfo, type AboutItem, type AccountMenuItem, type AccountMenuStat, ActionButton, ActionIcon, ActionSearch, ColorList, type ColorListProps, CubeApp, type CubeAppAboutInfo, type CubeAppContextValue, type CubeAppProps, CubeConfigProvider, type CubeConfigProviderProps, CubePage, type CubePageProps, CubeSearchPage, type CubeSearchPageProps, DEFAULT_MOBILE_BREAKPOINT, DelayedLoading, type DelayedLoadingProps, DesktopOnly, EmptyTip, type EmptyTipProps, MARK_COLORS, MARK_COLORS_MAP, MARK_COLORS_WITH_EMPTY, MobileAccountSheet, type MobileAccountSheetProps, MobileOnly, PageLoading, type PageLoadingProps, type ResponsiveProps, type UseMediaQueryOptions, getColorValue, useCubeAppContext, useCubeAppHeaderLeft, useIsMobile, useMediaQuery };
package/dist/index.js CHANGED
@@ -74,11 +74,6 @@ import { SearchOutlined, SmileOutlined } from "@ant-design/icons";
74
74
 
75
75
  // src/app-header/app-header.tsx
76
76
  import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
77
-
78
- // src/app-header/app-header.module.css
79
- var app_header_default = {};
80
-
81
- // src/app-header/app-header.tsx
82
77
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
83
78
  var AppHeader = ({
84
79
  title,
@@ -91,22 +86,22 @@ var AppHeader = ({
91
86
  }) => {
92
87
  const label = collapsed ? "\u5C55\u5F00\u4FA7\u8FB9\u680F" : "\u6536\u8D77\u4FA7\u8FB9\u680F";
93
88
  const ToggleIcon = collapsed ? MenuUnfoldOutlined : MenuFoldOutlined;
94
- return /* @__PURE__ */ jsxs("header", { className: [app_header_default.root, className].filter(Boolean).join(" "), ...headerProps, children: [
95
- /* @__PURE__ */ jsxs("div", { className: app_header_default.leading, children: [
89
+ return /* @__PURE__ */ jsxs("header", { className: ["cube-app-header", className].filter(Boolean).join(" "), ...headerProps, children: [
90
+ /* @__PURE__ */ jsxs("div", { className: "cube-app-header-leading", children: [
96
91
  showSidebarToggle ? /* @__PURE__ */ jsx2(
97
92
  "button",
98
93
  {
99
94
  type: "button",
100
- className: app_header_default.toggle,
95
+ className: "cube-app-header-toggle",
101
96
  "aria-label": label,
102
97
  "aria-expanded": !collapsed,
103
98
  onClick: onToggleSidebar,
104
99
  children: /* @__PURE__ */ jsx2(ToggleIcon, { "aria-hidden": true })
105
100
  }
106
101
  ) : null,
107
- /* @__PURE__ */ jsx2("div", { className: app_header_default.title, children: title })
102
+ /* @__PURE__ */ jsx2("div", { className: "cube-app-header-title", children: title })
108
103
  ] }),
109
- actions ? /* @__PURE__ */ jsx2("div", { className: app_header_default.actions, children: actions }) : null
104
+ actions ? /* @__PURE__ */ jsx2("div", { className: "cube-app-header-actions", children: actions }) : null
110
105
  ] });
111
106
  };
112
107
 
@@ -114,11 +109,6 @@ var AppHeader = ({
114
109
  import { useState } from "react";
115
110
  import { UserOutlined } from "@ant-design/icons";
116
111
  import { Popover } from "antd";
117
-
118
- // src/account-menu/account-menu.module.css
119
- var account_menu_default = {};
120
-
121
- // src/account-menu/account-menu-button.tsx
122
112
  import { jsx as jsx3 } from "react/jsx-runtime";
123
113
  var AccountMenuButton = ({ content }) => {
124
114
  const [open, setOpen] = useState(false);
@@ -137,7 +127,7 @@ var AccountMenuButton = ({ content }) => {
137
127
  "button",
138
128
  {
139
129
  type: "button",
140
- className: account_menu_default.trigger,
130
+ className: "cube-account-trigger",
141
131
  "aria-label": "\u6253\u5F00\u7528\u6237\u83DC\u5355",
142
132
  "aria-expanded": open,
143
133
  "aria-haspopup": "dialog",
@@ -151,9 +141,9 @@ var AccountMenuButton = ({ content }) => {
151
141
  // src/account-menu/account-menu.tsx
152
142
  import { Button, Statistic } from "antd";
153
143
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
154
- var AccountMenu = ({ stats = [], items = [], footer }) => /* @__PURE__ */ jsxs2("div", { className: account_menu_default.menu, children: [
155
- stats.length > 0 ? /* @__PURE__ */ jsx4("div", { className: account_menu_default.stats, children: stats.map((stat) => /* @__PURE__ */ jsx4(Statistic, { title: stat.title, value: stat.value, prefix: stat.icon }, stat.key)) }) : null,
156
- items.length > 0 ? /* @__PURE__ */ jsx4("div", { className: account_menu_default.items, children: items.map((item) => /* @__PURE__ */ jsx4(
144
+ var AccountMenu = ({ stats = [], items = [], footer }) => /* @__PURE__ */ jsxs2("div", { className: "cube-account-menu", children: [
145
+ stats.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "cube-account-menu-stats", children: stats.map((stat) => /* @__PURE__ */ jsx4(Statistic, { title: stat.title, value: stat.value, prefix: stat.icon }, stat.key)) }) : null,
146
+ items.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "cube-account-menu-items", children: items.map((item) => /* @__PURE__ */ jsx4(
157
147
  Button,
158
148
  {
159
149
  block: true,
@@ -166,30 +156,25 @@ var AccountMenu = ({ stats = [], items = [], footer }) => /* @__PURE__ */ jsxs2(
166
156
  },
167
157
  item.key
168
158
  )) }) : null,
169
- footer ? /* @__PURE__ */ jsx4("div", { className: account_menu_default.footer, children: footer }) : null
159
+ footer ? /* @__PURE__ */ jsx4("div", { className: "cube-account-menu-footer", children: footer }) : null
170
160
  ] });
171
161
 
172
162
  // src/about-dialog/about-dialog.tsx
173
163
  import { BarcodeOutlined, GithubOutlined, SendOutlined } from "@ant-design/icons";
174
164
  import { Flex, Modal } from "antd";
175
-
176
- // src/about-dialog/about-dialog.module.css
177
- var about_dialog_default = {};
178
-
179
- // src/about-dialog/about-dialog.tsx
180
165
  import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
181
166
  var renderItem = (item) => {
182
- const content = /* @__PURE__ */ jsx5("div", { className: about_dialog_default.item, children: /* @__PURE__ */ jsxs3(Flex, { justify: "space-between", gap: 16, children: [
183
- /* @__PURE__ */ jsxs3("div", { className: about_dialog_default.itemLabel, children: [
167
+ const content = /* @__PURE__ */ jsx5("div", { className: "cube-about-item", children: /* @__PURE__ */ jsxs3(Flex, { justify: "space-between", gap: 16, children: [
168
+ /* @__PURE__ */ jsxs3("div", { className: "cube-about-item-label", children: [
184
169
  item.icon ? /* @__PURE__ */ jsxs3(Fragment, { children: [
185
170
  item.icon,
186
171
  " \xA0"
187
172
  ] }) : null,
188
173
  item.label
189
174
  ] }),
190
- /* @__PURE__ */ jsx5("div", { className: about_dialog_default.itemValue, children: item.value })
175
+ /* @__PURE__ */ jsx5("div", { className: "cube-about-item-value", children: item.value })
191
176
  ] }) });
192
- return item.href ? /* @__PURE__ */ jsx5("a", { href: item.href, className: about_dialog_default.link, children: content }, item.key) : /* @__PURE__ */ jsx5("div", { children: content }, item.key);
177
+ return item.href ? /* @__PURE__ */ jsx5("a", { href: item.href, className: "cube-about-link", children: content }, item.key) : /* @__PURE__ */ jsx5("div", { children: content }, item.key);
193
178
  };
194
179
  var AboutDialog = ({
195
180
  open,
@@ -243,7 +228,7 @@ var AboutDialog = ({
243
228
  justify: author ? "space-between" : "flex-end",
244
229
  gap: 16,
245
230
  children: [
246
- author ? /* @__PURE__ */ jsxs3("div", { className: about_dialog_default.poweredBy, children: [
231
+ author ? /* @__PURE__ */ jsxs3("div", { className: "cube-about-powered-by", children: [
247
232
  "Powered by \u{1F497}",
248
233
  " ",
249
234
  author.url ? /* @__PURE__ */ jsx5("a", { href: author.url, children: author.name }) : author.name
@@ -252,17 +237,14 @@ var AboutDialog = ({
252
237
  ]
253
238
  }
254
239
  ),
255
- children: /* @__PURE__ */ jsxs3(Flex, { gap: 16, vertical: true, className: about_dialog_default.body, children: [
256
- app.description ? /* @__PURE__ */ jsx5("div", { className: about_dialog_default.description, children: app.description }) : null,
240
+ children: /* @__PURE__ */ jsxs3(Flex, { gap: 16, vertical: true, className: "cube-about-body", children: [
241
+ app.description ? /* @__PURE__ */ jsx5("div", { className: "cube-about-description", children: app.description }) : null,
257
242
  renderedItems.map(renderItem)
258
243
  ] })
259
244
  }
260
245
  );
261
246
  };
262
247
 
263
- // src/cube-app/cube-app.module.css
264
- var cube_app_default = {};
265
-
266
248
  // src/cube-app/cube-app.tsx
267
249
  import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
268
250
  var CubeAppContext = createContext({
@@ -355,7 +337,7 @@ var CubeApp = ({
355
337
  );
356
338
  const renderShell = () => {
357
339
  if (isMobile) {
358
- return /* @__PURE__ */ jsx6("div", { className: cube_app_default.mobileRoot, "data-testid": "cube-app-shell-mobile", children: /* @__PURE__ */ jsx6("main", { className: cube_app_default.mobileContent, children }) });
340
+ return /* @__PURE__ */ jsx6("div", { className: "cube-app-mobile-root", "data-testid": "cube-app-shell-mobile", children: /* @__PURE__ */ jsx6("main", { className: "cube-app-mobile-content", children }) });
359
341
  }
360
342
  const sidebarStyle = {
361
343
  width: collapsed ? "0px" : SIDEBAR_WIDTH
@@ -363,22 +345,22 @@ var CubeApp = ({
363
345
  const contentStyle = {
364
346
  width: collapsed ? "100vw" : `calc(100vw - ${SIDEBAR_WIDTH})`
365
347
  };
366
- return /* @__PURE__ */ jsxs4("div", { className: cube_app_default.root, "data-testid": "cube-app-shell", children: [
348
+ return /* @__PURE__ */ jsxs4("div", { className: "cube-app-root", "data-testid": "cube-app-shell", children: [
367
349
  /* @__PURE__ */ jsxs4(
368
350
  "aside",
369
351
  {
370
- className: cube_app_default.sidebar,
352
+ className: "cube-app-sidebar",
371
353
  style: sidebarStyle,
372
354
  "data-testid": "cube-app-shell-sidebar",
373
355
  "aria-hidden": collapsed,
374
356
  children: [
375
- sidebarTop ? /* @__PURE__ */ jsx6("div", { className: cube_app_default.sidebarTop, children: sidebarTop }) : null,
376
- /* @__PURE__ */ jsx6("div", { className: cube_app_default.sidebarList, children: sidebarList }),
377
- sidebarBottom ? /* @__PURE__ */ jsx6("div", { className: cube_app_default.sidebarBottom, children: sidebarBottom }) : null
357
+ sidebarTop ? /* @__PURE__ */ jsx6("div", { className: "cube-app-sidebar-top", children: sidebarTop }) : null,
358
+ /* @__PURE__ */ jsx6("div", { className: "cube-app-sidebar-list", children: sidebarList }),
359
+ sidebarBottom ? /* @__PURE__ */ jsx6("div", { className: "cube-app-sidebar-bottom", children: sidebarBottom }) : null
378
360
  ]
379
361
  }
380
362
  ),
381
- /* @__PURE__ */ jsxs4("div", { className: cube_app_default.desktopArea, style: contentStyle, children: [
363
+ /* @__PURE__ */ jsxs4("div", { className: "cube-app-desktop-area", style: contentStyle, children: [
382
364
  /* @__PURE__ */ jsx6(
383
365
  AppHeader,
384
366
  {
@@ -390,7 +372,7 @@ var CubeApp = ({
390
372
  onHeaderSearchBtnClick ? /* @__PURE__ */ jsx6(
391
373
  Button2,
392
374
  {
393
- className: cube_app_default.searchButton,
375
+ className: "cube-app-search-button",
394
376
  icon: /* @__PURE__ */ jsx6(SearchOutlined, { "aria-hidden": true }),
395
377
  "aria-label": headerSearchBtnLabel ?? "\u641C\u7D22",
396
378
  onClick: onHeaderSearchBtnClick,
@@ -401,7 +383,7 @@ var CubeApp = ({
401
383
  ] })
402
384
  }
403
385
  ),
404
- /* @__PURE__ */ jsx6("main", { className: cube_app_default.content, children })
386
+ /* @__PURE__ */ jsx6("main", { className: "cube-app-content", children })
405
387
  ] })
406
388
  ] });
407
389
  };
@@ -424,16 +406,11 @@ var CubeApp = ({
424
406
  // src/mobile-account-sheet/mobile-account-sheet.tsx
425
407
  import { Fragment as Fragment3 } from "react";
426
408
  import { Button as Button3, Drawer, Flex as Flex2, Statistic as Statistic2 } from "antd";
427
-
428
- // src/mobile-account-sheet/mobile-account-sheet.module.css
429
- var mobile_account_sheet_default = {};
430
-
431
- // src/mobile-account-sheet/mobile-account-sheet.tsx
432
409
  import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
433
- var Cell = ({ title, extra, onClick }) => onClick ? /* @__PURE__ */ jsxs5("button", { type: "button", className: mobile_account_sheet_default.cell, onClick, children: [
410
+ var Cell = ({ title, extra, onClick }) => onClick ? /* @__PURE__ */ jsxs5("button", { type: "button", className: "cube-sheet-cell", onClick, children: [
434
411
  /* @__PURE__ */ jsx7("span", { children: title }),
435
412
  extra ? /* @__PURE__ */ jsx7("span", { children: extra }) : null
436
- ] }) : /* @__PURE__ */ jsxs5("div", { className: mobile_account_sheet_default.cell, children: [
413
+ ] }) : /* @__PURE__ */ jsxs5("div", { className: "cube-sheet-cell", children: [
437
414
  /* @__PURE__ */ jsx7("span", { children: title }),
438
415
  extra ? /* @__PURE__ */ jsx7("span", { children: extra }) : null
439
416
  ] });
@@ -455,9 +432,9 @@ var MobileAccountSheet = ({ visible, onVisibleChange }) => {
455
432
  },
456
433
  footer: /* @__PURE__ */ jsx7(Button3, { block: true, size: "large", type: "primary", "aria-label": "\u8FD4\u56DE", onClick: close, children: "\u8FD4\u56DE" }),
457
434
  children: /* @__PURE__ */ jsxs5(Flex2, { vertical: true, gap: 12, children: [
458
- accountMenuStats && accountMenuStats.length > 0 ? /* @__PURE__ */ jsx7("div", { className: mobile_account_sheet_default.card, children: /* @__PURE__ */ jsx7(Flex2, { justify: "space-around", children: accountMenuStats.map((stat) => /* @__PURE__ */ jsx7(Statistic2, { title: stat.title, value: stat.value, prefix: stat.icon }, stat.key)) }) }) : null,
459
- userName ? /* @__PURE__ */ jsx7("div", { className: mobile_account_sheet_default.card, children: /* @__PURE__ */ jsx7(Cell, { title: "\u767B\u5F55\u7528\u6237", extra: userName }) }) : null,
460
- accountMenuItems && accountMenuItems.length > 0 ? /* @__PURE__ */ jsx7("div", { className: mobile_account_sheet_default.card, children: accountMenuItems.map((item, index) => /* @__PURE__ */ jsxs5(Fragment3, { children: [
435
+ accountMenuStats && accountMenuStats.length > 0 ? /* @__PURE__ */ jsx7("div", { className: "cube-sheet-card", children: /* @__PURE__ */ jsx7(Flex2, { justify: "space-around", children: accountMenuStats.map((stat) => /* @__PURE__ */ jsx7(Statistic2, { title: stat.title, value: stat.value, prefix: stat.icon }, stat.key)) }) }) : null,
436
+ userName ? /* @__PURE__ */ jsx7("div", { className: "cube-sheet-card", children: /* @__PURE__ */ jsx7(Cell, { title: "\u767B\u5F55\u7528\u6237", extra: userName }) }) : null,
437
+ accountMenuItems && accountMenuItems.length > 0 ? /* @__PURE__ */ jsx7("div", { className: "cube-sheet-card", children: accountMenuItems.map((item, index) => /* @__PURE__ */ jsxs5(Fragment3, { children: [
461
438
  /* @__PURE__ */ jsx7(
462
439
  Cell,
463
440
  {
@@ -472,9 +449,9 @@ var MobileAccountSheet = ({ visible, onVisibleChange }) => {
472
449
  }
473
450
  }
474
451
  ),
475
- index !== accountMenuItems.length - 1 ? /* @__PURE__ */ jsx7("div", { className: mobile_account_sheet_default.splitLine }) : null
452
+ index !== accountMenuItems.length - 1 ? /* @__PURE__ */ jsx7("div", { className: "cube-sheet-split-line" }) : null
476
453
  ] }, item.key)) }) : null,
477
- onLogoutBtnClick ? /* @__PURE__ */ jsx7("div", { className: mobile_account_sheet_default.card, children: /* @__PURE__ */ jsx7(
454
+ onLogoutBtnClick ? /* @__PURE__ */ jsx7("div", { className: "cube-sheet-card", children: /* @__PURE__ */ jsx7(
478
455
  Cell,
479
456
  {
480
457
  title: "\u767B\u51FA",
@@ -492,13 +469,8 @@ var MobileAccountSheet = ({ visible, onVisibleChange }) => {
492
469
  // src/loading/loading.tsx
493
470
  import { useEffect as useEffect2, useState as useState3 } from "react";
494
471
  import { Flex as Flex3 } from "antd";
495
-
496
- // src/loading/loading.module.css
497
- var loading_default = {};
498
-
499
- // src/loading/loading.tsx
500
472
  import { jsx as jsx8 } from "react/jsx-runtime";
501
- var PageLoading = ({ tip = "\u52A0\u8F7D\u4E2D..." }) => /* @__PURE__ */ jsx8(Flex3, { justify: "center", align: "center", className: loading_default.pageLoading, children: tip });
473
+ var PageLoading = ({ tip = "\u52A0\u8F7D\u4E2D..." }) => /* @__PURE__ */ jsx8(Flex3, { justify: "center", align: "center", className: "cube-page-loading", children: tip });
502
474
  var DelayedLoading = ({
503
475
  tip = "\u9875\u9762\u52A0\u8F7D\u4E2D...",
504
476
  delay = 500,
@@ -514,7 +486,7 @@ var DelayedLoading = ({
514
486
  return /* @__PURE__ */ jsx8(
515
487
  "div",
516
488
  {
517
- className: [loading_default.delayedLoading, className].filter(Boolean).join(" "),
489
+ className: ["cube-delayed-loading", className].filter(Boolean).join(" "),
518
490
  ...props,
519
491
  children: tip
520
492
  }
@@ -522,17 +494,13 @@ var DelayedLoading = ({
522
494
  };
523
495
 
524
496
  // src/page/page.tsx
525
- import { Button as Button4 } from "antd";
526
-
527
- // src/page/page.module.css
528
- var page_default = {};
529
-
530
- // src/page/page.tsx
497
+ import { Button as Button4, Input } from "antd";
498
+ import { SearchOutlined as SearchOutlined2 } from "@ant-design/icons";
531
499
  import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
532
- var PageContainer = ({ children }) => /* @__PURE__ */ jsx9("div", { className: page_default.container, children });
533
- var PageContent = ({ children }) => /* @__PURE__ */ jsx9("div", { className: page_default.content, children });
534
- var PageActionBar = ({ children }) => /* @__PURE__ */ jsx9(MobileOnly, { children: /* @__PURE__ */ jsx9("div", { className: page_default.actionBar, children }) });
535
- var ActionIcon = ({ className, size = "large", ...props }) => /* @__PURE__ */ jsx9(Button4, { className: [page_default.actionIcon, className].filter(Boolean).join(" "), size, ...props });
500
+ var PageContainer = ({ children }) => /* @__PURE__ */ jsx9("div", { className: "cube-page-container", children });
501
+ var PageContent = ({ children }) => /* @__PURE__ */ jsx9("div", { className: "cube-page-content", children });
502
+ var PageActionBar = ({ children }) => /* @__PURE__ */ jsx9(MobileOnly, { children: /* @__PURE__ */ jsx9("div", { className: "cube-page-action-bar", children }) });
503
+ var ActionIcon = ({ className, size = "large", ...props }) => /* @__PURE__ */ jsx9(Button4, { className: ["cube-page-action-icon", className].filter(Boolean).join(" "), size, ...props });
536
504
  var ActionButton = ({
537
505
  children,
538
506
  type = "primary",
@@ -540,6 +508,17 @@ var ActionButton = ({
540
508
  size = "large",
541
509
  ...props
542
510
  }) => /* @__PURE__ */ jsx9(Button4, { block, size, type, ...props, children });
511
+ var ActionSearch = ({ className, ...props }) => /* @__PURE__ */ jsx9(
512
+ Input.Search,
513
+ {
514
+ placeholder: "\u8F93\u5165\u5173\u952E\u5B57\u641C\u7D22",
515
+ enterButton: /* @__PURE__ */ jsx9(SearchOutlined2, {}),
516
+ size: "large",
517
+ autoFocus: true,
518
+ ...props,
519
+ className: ["cube-page-action-search", className].filter(Boolean).join(" ")
520
+ }
521
+ );
543
522
  var CubePage = ({ desktopHeaderLeft, mobileActionBar, children }) => {
544
523
  useCubeAppHeaderLeft(desktopHeaderLeft);
545
524
  return /* @__PURE__ */ jsxs6(PageContainer, { children: [
@@ -547,18 +526,215 @@ var CubePage = ({ desktopHeaderLeft, mobileActionBar, children }) => {
547
526
  mobileActionBar ? /* @__PURE__ */ jsx9(PageActionBar, { children: mobileActionBar }) : null
548
527
  ] });
549
528
  };
529
+
530
+ // src/empty-tip/empty-tip.tsx
531
+ import { Flex as Flex4 } from "antd";
532
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
533
+ var EmptyTip = ({ title, subTitle, extra, className }) => /* @__PURE__ */ jsxs7(
534
+ Flex4,
535
+ {
536
+ vertical: true,
537
+ gap: 4,
538
+ align: "center",
539
+ justify: "center",
540
+ className: ["cube-empty-tip", className].filter(Boolean).join(" "),
541
+ children: [
542
+ title ? /* @__PURE__ */ jsx10("div", { className: "cube-empty-tip-title", children: title }) : null,
543
+ subTitle ? /* @__PURE__ */ jsx10("div", { className: "cube-empty-tip-subtitle", children: subTitle }) : null,
544
+ extra ? /* @__PURE__ */ jsx10("div", { children: extra }) : null
545
+ ]
546
+ }
547
+ );
548
+
549
+ // src/color-list/color-list.tsx
550
+ import { Flex as Flex5 } from "antd";
551
+ import { jsx as jsx11 } from "react/jsx-runtime";
552
+ var MARK_COLORS_MAP = {
553
+ c1: "#ef4444",
554
+ c2: "#f97316",
555
+ c3: "#f59e0b",
556
+ c4: "#eab308",
557
+ c5: "#84cc16",
558
+ c6: "#22c55e",
559
+ c7: "#10b981",
560
+ c8: "#14b8a6",
561
+ c9: "#06b6d4",
562
+ c10: "#0ea5e9",
563
+ c11: "#3b82f6",
564
+ c12: "#6366f1",
565
+ c13: "#8b5cf6",
566
+ c14: "#a855f7",
567
+ c15: "#d946ef",
568
+ c16: "#ec4899"
569
+ };
570
+ var MARK_COLORS = [
571
+ "c1",
572
+ "c2",
573
+ "c3",
574
+ "c4",
575
+ "c5",
576
+ "c6",
577
+ "c7",
578
+ "c8",
579
+ "c9",
580
+ "c10",
581
+ "c11",
582
+ "c12",
583
+ "c13",
584
+ "c14",
585
+ "c15",
586
+ "c16"
587
+ ];
588
+ var MARK_COLORS_WITH_EMPTY = [...MARK_COLORS, ""];
589
+ var getColorValue = (colorCode) => MARK_COLORS_MAP[colorCode];
590
+ var ColorItem = ({ colorCode, selected, onClick }) => {
591
+ const classes = ["cube-color-dot"];
592
+ if (selected) classes.push("cube-color-dot-selected");
593
+ if (colorCode === "") classes.push("cube-color-dot-clear");
594
+ return /* @__PURE__ */ jsx11(
595
+ "button",
596
+ {
597
+ type: "button",
598
+ "aria-label": colorCode === "" ? "\u6E05\u9664\u989C\u8272" : `\u989C\u8272 ${colorCode}`,
599
+ className: classes.join(" "),
600
+ style: { backgroundColor: MARK_COLORS_MAP[colorCode] },
601
+ onClick: () => onClick(colorCode)
602
+ }
603
+ );
604
+ };
605
+ var ColorList = ({ value, onChange, flexProps }) => /* @__PURE__ */ jsx11(Flex5, { wrap: true, gap: 8, ...flexProps, children: MARK_COLORS_WITH_EMPTY.map((colorCode) => /* @__PURE__ */ jsx11(
606
+ ColorItem,
607
+ {
608
+ colorCode,
609
+ selected: value === colorCode,
610
+ onClick: (next) => onChange?.(next)
611
+ },
612
+ colorCode || "clear"
613
+ )) });
614
+
615
+ // src/search-page/search-page.tsx
616
+ import { useState as useState4 } from "react";
617
+ import { Button as Button5, Col, Drawer as Drawer2, Flex as Flex6, Input as Input2, Row } from "antd";
618
+ import { FilterOutlined, LeftOutlined } from "@ant-design/icons";
619
+ import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
620
+ var CubeSearchPage = ({
621
+ keyword = "",
622
+ placeholder = "\u8BF7\u8F93\u5165\u5173\u952E\u5B57\uFF0C\u56DE\u8F66\u641C\u7D22",
623
+ searchButtonLabel = "\u641C\u7D22",
624
+ onSearch,
625
+ onBack,
626
+ desktopHeaderLeft,
627
+ filters,
628
+ mobileFilterTitle = "\u7B5B\u9009",
629
+ mobileFilterIcon,
630
+ pending = false,
631
+ loading = false,
632
+ empty = false,
633
+ pendingHint = "\u53EF\u4F7F\u7528\u5173\u952E\u8BCD\u548C\u989C\u8272\u8FDB\u884C\u641C\u7D22",
634
+ loadingTitle = "\u6B63\u5728\u641C\u7D22\u4E2D...",
635
+ loadingHint = "\u8BF7\u7A0D\u5019",
636
+ emptyTitle = "\u6CA1\u6709\u627E\u5230\u76F8\u5173\u7ED3\u679C",
637
+ emptyHint = "\u8BF7\u5C1D\u8BD5\u5176\u4ED6\u5173\u952E\u5B57",
638
+ children
639
+ }) => {
640
+ const [filterOpen, setFilterOpen] = useState4(false);
641
+ const hasFilters = filters != null;
642
+ const renderBody = () => {
643
+ if (loading) {
644
+ return /* @__PURE__ */ jsx12(EmptyTip, { title: loadingTitle, subTitle: loadingHint });
645
+ }
646
+ if (pending) {
647
+ return /* @__PURE__ */ jsx12(EmptyTip, { subTitle: pendingHint });
648
+ }
649
+ if (empty) {
650
+ return /* @__PURE__ */ jsx12("div", { "data-testid": "search-empty-tip", children: /* @__PURE__ */ jsx12(EmptyTip, { title: emptyTitle, subTitle: emptyHint }) });
651
+ }
652
+ return /* @__PURE__ */ jsx12(
653
+ Flex6,
654
+ {
655
+ vertical: true,
656
+ align: "center",
657
+ gap: 8,
658
+ className: "cube-search-page-results",
659
+ "data-testid": "search-result-list",
660
+ children
661
+ }
662
+ );
663
+ };
664
+ return /* @__PURE__ */ jsxs8(Fragment5, { children: [
665
+ /* @__PURE__ */ jsx12(
666
+ CubePage,
667
+ {
668
+ desktopHeaderLeft,
669
+ mobileActionBar: /* @__PURE__ */ jsxs8(Fragment5, { children: [
670
+ /* @__PURE__ */ jsx12(ActionIcon, { icon: /* @__PURE__ */ jsx12(LeftOutlined, {}), "aria-label": "\u8FD4\u56DE", onClick: onBack }),
671
+ hasFilters ? /* @__PURE__ */ jsx12(
672
+ ActionIcon,
673
+ {
674
+ icon: mobileFilterIcon ?? /* @__PURE__ */ jsx12(FilterOutlined, {}),
675
+ "aria-label": "\u6253\u5F00\u7B5B\u9009",
676
+ onClick: () => setFilterOpen(true)
677
+ }
678
+ ) : null,
679
+ /* @__PURE__ */ jsx12(ActionSearch, { defaultValue: keyword, onSearch })
680
+ ] }),
681
+ children: /* @__PURE__ */ jsxs8(Flex6, { vertical: true, gap: 16, align: "center", className: "cube-search-page", children: [
682
+ /* @__PURE__ */ jsx12(DesktopOnly, { children: /* @__PURE__ */ jsx12(
683
+ Input2.Search,
684
+ {
685
+ placeholder,
686
+ enterButton: searchButtonLabel,
687
+ autoFocus: true,
688
+ size: "large",
689
+ defaultValue: keyword,
690
+ onSearch,
691
+ className: "cube-search-page-input",
692
+ "data-testid": "search-keyword-input"
693
+ }
694
+ ) }),
695
+ hasFilters ? /* @__PURE__ */ jsx12(DesktopOnly, { children: filters }) : null,
696
+ renderBody()
697
+ ] })
698
+ }
699
+ ),
700
+ hasFilters ? /* @__PURE__ */ jsx12(MobileOnly, { children: /* @__PURE__ */ jsx12(
701
+ Drawer2,
702
+ {
703
+ title: mobileFilterTitle,
704
+ open: filterOpen,
705
+ onClose: () => setFilterOpen(false),
706
+ placement: "bottom",
707
+ closable: false,
708
+ styles: {
709
+ footer: { padding: 8, border: "none" },
710
+ header: { textAlign: "center", padding: 8 }
711
+ },
712
+ footer: /* @__PURE__ */ jsx12(Row, { gutter: 8, children: /* @__PURE__ */ jsx12(Col, { flex: "1", children: /* @__PURE__ */ jsx12(Button5, { block: true, size: "large", onClick: () => setFilterOpen(false), children: "\u786E\u5B9A" }) }) }),
713
+ children: /* @__PURE__ */ jsx12(Flex6, { vertical: true, gap: 16, className: "cube-search-page-drawer", align: "center", children: filters })
714
+ }
715
+ ) }) : null
716
+ ] });
717
+ };
550
718
  export {
551
719
  ActionButton,
552
720
  ActionIcon,
721
+ ActionSearch,
722
+ ColorList,
553
723
  CubeApp,
554
724
  CubeConfigProvider,
555
725
  CubePage,
726
+ CubeSearchPage,
556
727
  DEFAULT_MOBILE_BREAKPOINT,
557
728
  DelayedLoading,
558
729
  DesktopOnly,
730
+ EmptyTip,
731
+ MARK_COLORS,
732
+ MARK_COLORS_MAP,
733
+ MARK_COLORS_WITH_EMPTY,
559
734
  MobileAccountSheet,
560
735
  MobileOnly,
561
736
  PageLoading,
737
+ getColorValue,
562
738
  useCubeAppContext,
563
739
  useCubeAppHeaderLeft,
564
740
  useIsMobile,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/responsive/responsive.tsx","../src/cube-config-provider/cube-config-provider.tsx","../src/cube-app/cube-app.tsx","../src/app-header/app-header.tsx","../src/app-header/app-header.module.css","../src/account-menu/account-menu-button.tsx","../src/account-menu/account-menu.module.css","../src/account-menu/account-menu.tsx","../src/about-dialog/about-dialog.tsx","../src/about-dialog/about-dialog.module.css","../src/cube-app/cube-app.module.css","../src/mobile-account-sheet/mobile-account-sheet.tsx","../src/mobile-account-sheet/mobile-account-sheet.module.css","../src/loading/loading.tsx","../src/loading/loading.module.css","../src/page/page.tsx","../src/page/page.module.css"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, useCallback, useMemo, useSyncExternalStore } from \"react\";\n\nexport const DEFAULT_MOBILE_BREAKPOINT = 767;\n\nexport interface UseMediaQueryOptions {\n defaultMatches?: boolean;\n}\n\nexport interface ResponsiveProps extends PropsWithChildren {\n defaultMatches?: boolean;\n}\n\nexport const useMediaQuery = (query: string, options: UseMediaQueryOptions = {}): boolean => {\n const { defaultMatches = false } = options;\n const mediaQueryList = useMemo(\n () =>\n typeof window !== \"undefined\" && typeof window.matchMedia === \"function\"\n ? window.matchMedia(query)\n : null,\n [query],\n );\n\n const subscribe = useCallback(\n (notify: () => void) => {\n if (!mediaQueryList) return () => undefined;\n mediaQueryList.addEventListener(\"change\", notify);\n return () => mediaQueryList.removeEventListener(\"change\", notify);\n },\n [mediaQueryList],\n );\n\n const getSnapshot = useCallback(\n () => mediaQueryList?.matches ?? defaultMatches,\n [defaultMatches, mediaQueryList],\n );\n const getServerSnapshot = useCallback(() => defaultMatches, [defaultMatches]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n};\n\nexport const useIsMobile = ({ defaultMatches }: UseMediaQueryOptions = {}): boolean =>\n useMediaQuery(`(max-width: ${DEFAULT_MOBILE_BREAKPOINT}px)`, { defaultMatches });\n\nexport const MobileOnly = ({ children, defaultMatches }: ResponsiveProps): ReactNode => {\n const isMobile = useIsMobile({ defaultMatches });\n return isMobile ? children : null;\n};\n\nexport const DesktopOnly = ({ children, defaultMatches }: ResponsiveProps): ReactNode => {\n const isMobile = useIsMobile({ defaultMatches });\n return isMobile ? null : children;\n};\n","import { useMemo, type ReactNode } from \"react\";\nimport { ConfigProvider } from \"antd\";\nimport zhCN from \"antd/locale/zh_CN\";\nimport { useIsMobile } from \"../responsive/responsive\";\n\nexport interface CubeConfigProviderProps {\n children: ReactNode;\n\n primaryColor?: string;\n}\n\nconst DEFAULT_PRIMARY_COLOR = \"#ec008c\";\n\n/**\n * Applies the fixed Cube antd configuration (`zh_CN` locale, `primaryColor` token, a larger\n * base font size on mobile) without rendering any application shell. Mount it on its own for\n * pages that should share the Cube theme but live outside `CubeApp` — `CubeApp` itself wraps\n * this component internally.\n */\nexport const CubeConfigProvider = ({ children, primaryColor }: CubeConfigProviderProps) => {\n const isMobile = useIsMobile();\n\n const theme = useMemo(\n () => ({\n token: {\n colorPrimary: primaryColor ?? DEFAULT_PRIMARY_COLOR,\n lineWidth: 2,\n controlOutlineWidth: 1,\n ...(isMobile ? { fontSize: 16 } : {}),\n },\n components: {\n Card: {\n colorBorderSecondary: \"var(--cube-border-color, #d1d5db)\",\n lineHeight: 1.6,\n },\n },\n }),\n [primaryColor, isMobile],\n );\n\n return (\n <ConfigProvider locale={zhCN} theme={theme}>\n {children}\n </ConfigProvider>\n );\n};\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { Button } from \"antd\";\nimport { SearchOutlined, SmileOutlined } from \"@ant-design/icons\";\nimport { useIsMobile } from \"../responsive/responsive\";\nimport { CubeConfigProvider } from \"../cube-config-provider/cube-config-provider\";\nimport { AppHeader } from \"../app-header/app-header\";\nimport { AccountMenuButton } from \"../account-menu/account-menu-button\";\nimport { AccountMenu, type AccountMenuItem, type AccountMenuStat } from \"../account-menu/account-menu\";\nimport {\n AboutDialog,\n type AboutAppInfo,\n type AboutAuthorInfo,\n type AboutItem,\n} from \"../about-dialog/about-dialog\";\nimport styles from \"./cube-app.module.css\";\n\nexport interface CubeAppAboutInfo extends AboutAppInfo {\n contactEmail?: string;\n author?: AboutAuthorInfo;\n items?: AboutItem[];\n}\n\nexport interface CubeAppContextValue {\n accountMenuStats?: AccountMenuStat[];\n accountMenuItems?: AccountMenuItem[];\n onLogoutBtnClick?(): void;\n userName?: ReactNode;\n openAbout(): void;\n setHeaderLeft(node: ReactNode): void;\n}\n\nconst CubeAppContext = createContext<CubeAppContextValue>({\n openAbout: () => undefined,\n setHeaderLeft: () => undefined,\n});\n\n/**\n * Reads the account/about configuration passed to `CubeApp`. Only needed by components\n * mounted elsewhere in the route tree (e.g. `MobileAccountSheet`) — `CubeApp` itself\n * already has this data as props.\n */\nexport const useCubeAppContext = (): CubeAppContextValue => useContext(CubeAppContext);\n\n/**\n * Lets the currently mounted page override `CubeApp`'s `headerLeft` slot. Resets to the\n * default `headerLeft` prop when the calling component unmounts.\n */\nexport const useCubeAppHeaderLeft = (node: ReactNode): void => {\n const { setHeaderLeft } = useCubeAppContext();\n\n useEffect(() => {\n setHeaderLeft(node);\n return () => setHeaderLeft(undefined);\n }, [node, setHeaderLeft]);\n};\n\nexport interface CubeAppProps {\n children: ReactNode;\n\n primaryColor?: string;\n\n accountMenuStats?: AccountMenuStat[];\n accountMenuItems?: AccountMenuItem[];\n onLogoutBtnClick?(): void;\n userName?: ReactNode;\n about: CubeAppAboutInfo;\n\n sidebarTop?: ReactNode;\n sidebarList?: ReactNode;\n sidebarBottom?: ReactNode;\n\n headerLeft?: ReactNode;\n headerRight?: ReactNode;\n headerSearchBtnLabel?: string;\n onHeaderSearchBtnClick?(): void;\n}\n\nconst SIDEBAR_WIDTH = \"var(--cube-sidebar-width, 15rem)\";\n\nexport const CubeApp = ({\n children,\n primaryColor,\n accountMenuStats,\n accountMenuItems,\n onLogoutBtnClick,\n userName,\n about,\n sidebarTop,\n sidebarList,\n sidebarBottom,\n headerLeft,\n headerRight,\n headerSearchBtnLabel,\n onHeaderSearchBtnClick,\n}: CubeAppProps) => {\n const isMobile = useIsMobile();\n const [collapsed, setCollapsed] = useState(false);\n const toggleSidebar = useCallback(() => setCollapsed((value) => !value), []);\n const [aboutOpen, setAboutOpen] = useState(false);\n const [headerLeftOverride, setHeaderLeftOverride] = useState<ReactNode>(undefined);\n\n const itemsWithAbout = useMemo<AccountMenuItem[]>(\n () => [\n ...(accountMenuItems ?? []),\n {\n key: \"cube-app-about\",\n label: \"关于\",\n icon: <SmileOutlined />,\n onClick: () => setAboutOpen(true),\n },\n ],\n [accountMenuItems],\n );\n\n const contextValue = useMemo<CubeAppContextValue>(\n () => ({\n accountMenuStats,\n accountMenuItems: itemsWithAbout,\n onLogoutBtnClick,\n userName,\n openAbout: () => setAboutOpen(true),\n setHeaderLeft: setHeaderLeftOverride,\n }),\n [accountMenuStats, itemsWithAbout, onLogoutBtnClick, userName],\n );\n\n const renderAccountMenuButton = () => (\n <AccountMenuButton\n content={({ close }) => (\n <AccountMenu\n stats={accountMenuStats}\n items={itemsWithAbout.map((item) => ({\n ...item,\n onClick: () => {\n item.onClick?.();\n close();\n },\n }))}\n footer={\n onLogoutBtnClick ? (\n <Button\n block\n danger\n aria-label=\"登出\"\n onClick={() => {\n onLogoutBtnClick();\n close();\n }}\n >\n 登出\n </Button>\n ) : undefined\n }\n />\n )}\n />\n );\n\n const renderShell = () => {\n if (isMobile) {\n return (\n <div className={styles.mobileRoot} data-testid=\"cube-app-shell-mobile\">\n <main className={styles.mobileContent}>{children}</main>\n </div>\n );\n }\n\n const sidebarStyle: CSSProperties = {\n width: collapsed ? \"0px\" : SIDEBAR_WIDTH,\n };\n const contentStyle: CSSProperties = {\n width: collapsed ? \"100vw\" : `calc(100vw - ${SIDEBAR_WIDTH})`,\n };\n\n return (\n <div className={styles.root} data-testid=\"cube-app-shell\">\n <aside\n className={styles.sidebar}\n style={sidebarStyle}\n data-testid=\"cube-app-shell-sidebar\"\n aria-hidden={collapsed}\n >\n {sidebarTop ? <div className={styles.sidebarTop}>{sidebarTop}</div> : null}\n <div className={styles.sidebarList}>{sidebarList}</div>\n {sidebarBottom ? <div className={styles.sidebarBottom}>{sidebarBottom}</div> : null}\n </aside>\n <div className={styles.desktopArea} style={contentStyle}>\n <AppHeader\n title={headerLeftOverride ?? headerLeft}\n collapsed={collapsed}\n onToggleSidebar={toggleSidebar}\n actions={\n <>\n {headerRight}\n {onHeaderSearchBtnClick ? (\n <Button\n className={styles.searchButton}\n icon={<SearchOutlined aria-hidden />}\n aria-label={headerSearchBtnLabel ?? \"\\u641c\\u7d22\"}\n onClick={onHeaderSearchBtnClick}\n >\n {headerSearchBtnLabel ?? \"\\u641c\\u7d22\"}\n </Button>\n ) : null}\n {renderAccountMenuButton()}\n </>\n }\n />\n <main className={styles.content}>{children}</main>\n </div>\n </div>\n );\n };\n\n return (\n <CubeConfigProvider primaryColor={primaryColor}>\n <CubeAppContext.Provider value={contextValue}>\n {renderShell()}\n <AboutDialog\n open={aboutOpen}\n onClose={() => setAboutOpen(false)}\n app={about}\n contactEmail={about.contactEmail}\n author={about.author}\n items={about.items}\n />\n </CubeAppContext.Provider>\n </CubeConfigProvider>\n );\n};\n","import type { HTMLAttributes, ReactNode } from \"react\";\nimport { MenuFoldOutlined, MenuUnfoldOutlined } from \"@ant-design/icons\";\nimport styles from \"./app-header.module.css\";\n\nexport interface AppHeaderProps extends Omit<HTMLAttributes<HTMLElement>, \"title\"> {\n title?: ReactNode;\n actions?: ReactNode;\n collapsed?: boolean;\n showSidebarToggle?: boolean;\n onToggleSidebar?(): void;\n}\n\nexport const AppHeader = ({\n title,\n actions,\n collapsed = false,\n onToggleSidebar,\n showSidebarToggle = onToggleSidebar !== undefined,\n className,\n ...headerProps\n}: AppHeaderProps) => {\n const label = collapsed ? \"展开侧边栏\" : \"收起侧边栏\";\n const ToggleIcon = collapsed ? MenuUnfoldOutlined : MenuFoldOutlined;\n\n return (\n <header className={[styles.root, className].filter(Boolean).join(\" \")} {...headerProps}>\n <div className={styles.leading}>\n {showSidebarToggle ? (\n <button\n type=\"button\"\n className={styles.toggle}\n aria-label={label}\n aria-expanded={!collapsed}\n onClick={onToggleSidebar}\n >\n <ToggleIcon aria-hidden />\n </button>\n ) : null}\n <div className={styles.title}>{title}</div>\n </div>\n {actions ? <div className={styles.actions}>{actions}</div> : null}\n </header>\n );\n};\n",".root {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: var(--cube-header-height, 3rem);\n padding: 0.5rem 1rem;\n overflow: hidden;\n box-sizing: border-box;\n color: inherit;\n background: var(--cube-surface-color, #fff);\n border-bottom: 1px solid var(--cube-border-color, #d1d5db);\n transition: color 200ms ease, background-color 200ms ease,\n border-color 200ms ease;\n}\n\n:global(.dark) .root,\n:global([data-theme=\"dark\"]) .root {\n background: var(--cube-dark-surface-color, #141414);\n border-bottom-color: var(--cube-dark-border-color, #374151);\n}\n\n.leading {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n}\n\n.toggle {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n padding: 0;\n margin: 0 1rem 0 0;\n font: inherit;\n font-size: 1.25rem;\n color: inherit;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.toggle:focus-visible {\n outline: 2px solid #1677ff;\n outline-offset: 3px;\n border-radius: 2px;\n}\n\n.title {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.actions {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 0.5rem;\n margin-left: 0.5rem;\n}\n","import { type ReactNode, useState } from \"react\";\nimport { UserOutlined } from \"@ant-design/icons\";\nimport { Popover } from \"antd\";\nimport styles from \"./account-menu.module.css\";\n\nexport interface AccountMenuRenderContext {\n close(): void;\n}\n\nexport interface AccountMenuButtonProps {\n content: ReactNode | ((context: AccountMenuRenderContext) => ReactNode);\n}\n\nexport const AccountMenuButton = ({ content }: AccountMenuButtonProps) => {\n const [open, setOpen] = useState(false);\n const close = () => setOpen(false);\n const renderedContent = typeof content === \"function\" ? content({ close }) : content;\n\n return (\n <Popover\n placement=\"bottomRight\"\n trigger=\"click\"\n content={renderedContent}\n open={open}\n onOpenChange={setOpen}\n arrow\n >\n <button\n type=\"button\"\n className={styles.trigger}\n aria-label=\"打开用户菜单\"\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n >\n <UserOutlined aria-hidden />\n </button>\n </Popover>\n );\n};\n",".trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.25rem;\n margin: 0;\n font: inherit;\n font-size: 1.25rem;\n line-height: 1;\n color: inherit;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.trigger:focus-visible {\n outline: 2px solid #1677ff;\n outline-offset: 3px;\n border-radius: 50%;\n}\n\n.menu {\n width: 16rem;\n max-width: calc(100vw - 2rem);\n}\n\n.stats {\n display: flex;\n justify-content: space-around;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.items {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.footer {\n margin-top: 0.5rem;\n}\n","import type { Key, ReactNode } from \"react\";\nimport { Button, Statistic } from \"antd\";\nimport styles from \"./account-menu.module.css\";\n\nexport interface AccountMenuStat {\n key: Key;\n title: ReactNode;\n value: string | number;\n icon?: ReactNode;\n}\n\nexport interface AccountMenuItem {\n key: Key;\n label: ReactNode;\n icon?: ReactNode;\n danger?: boolean;\n disabled?: boolean;\n onClick?(): void;\n}\n\nexport interface AccountMenuProps {\n stats?: AccountMenuStat[];\n items?: AccountMenuItem[];\n footer?: ReactNode;\n}\n\nexport const AccountMenu = ({ stats = [], items = [], footer }: AccountMenuProps) => (\n <div className={styles.menu}>\n {stats.length > 0 ? (\n <div className={styles.stats}>\n {stats.map((stat) => (\n <Statistic key={stat.key} title={stat.title} value={stat.value} prefix={stat.icon} />\n ))}\n </div>\n ) : null}\n {items.length > 0 ? (\n <div className={styles.items}>\n {items.map((item) => (\n <Button\n key={item.key}\n block\n icon={item.icon}\n danger={item.danger}\n disabled={item.disabled}\n aria-label={typeof item.label === \"string\" ? item.label : undefined}\n onClick={item.onClick}\n >\n {item.label}\n </Button>\n ))}\n </div>\n ) : null}\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </div>\n);\n","import type { Key, ReactNode } from \"react\";\nimport { BarcodeOutlined, GithubOutlined, SendOutlined } from \"@ant-design/icons\";\nimport { Flex, Modal } from \"antd\";\nimport styles from \"./about-dialog.module.css\";\n\nexport interface AboutAppInfo {\n name: string;\n version?: string;\n repository?: string;\n description?: ReactNode;\n}\n\nexport interface AboutAuthorInfo {\n name: string;\n url?: string;\n}\n\nexport interface AboutItem {\n key: Key;\n icon?: ReactNode;\n label: ReactNode;\n value: ReactNode;\n href?: string;\n}\n\nexport interface AboutDialogProps {\n open: boolean;\n onClose(): void;\n app: AboutAppInfo;\n contactEmail?: string;\n author?: AboutAuthorInfo;\n items?: AboutItem[];\n}\n\nconst renderItem = (item: AboutItem) => {\n const content = (\n <div className={styles.item}>\n <Flex justify=\"space-between\" gap={16}>\n <div className={styles.itemLabel}>\n {item.icon ? <>{item.icon} &nbsp;</> : null}\n {item.label}\n </div>\n <div className={styles.itemValue}>{item.value}</div>\n </Flex>\n </div>\n );\n\n return item.href ? (\n <a key={item.key} href={item.href} className={styles.link}>\n {content}\n </a>\n ) : (\n <div key={item.key}>{content}</div>\n );\n};\n\nexport const AboutDialog = ({\n open,\n onClose,\n app,\n contactEmail,\n author,\n items = [],\n}: AboutDialogProps) => {\n const defaultItems: AboutItem[] = [];\n\n if (contactEmail) {\n defaultItems.push({\n key: \"contact\",\n icon: <SendOutlined />,\n label: \"联系我\",\n value: contactEmail,\n href: `mailto:${contactEmail}?&subject=${encodeURIComponent(\n `${app.name} 相关`,\n )}`,\n });\n }\n\n if (app.version) {\n defaultItems.push({\n key: \"version\",\n icon: <BarcodeOutlined />,\n label: \"当前版本\",\n value: app.version,\n });\n }\n\n if (app.repository) {\n defaultItems.push({\n key: \"repository\",\n icon: <GithubOutlined />,\n label: \"开源地址\",\n value: \"github\",\n href: app.repository,\n });\n }\n\n const renderedItems = [...defaultItems, ...items];\n\n return (\n <Modal\n open={open}\n onCancel={onClose}\n onOk={onClose}\n title={`关于应用 ${app.name}`}\n footer={(_, { OkBtn }) => (\n <Flex\n align=\"center\"\n justify={author ? \"space-between\" : \"flex-end\"}\n gap={16}\n >\n {author ? (\n <div className={styles.poweredBy}>\n Powered by 💗{\" \"}\n {author.url ? (\n <a href={author.url}>{author.name}</a>\n ) : (\n author.name\n )}\n </div>\n ) : null}\n <OkBtn />\n </Flex>\n )}\n >\n <Flex gap={16} vertical className={styles.body}>\n {app.description ? (\n <div className={styles.description}>{app.description}</div>\n ) : null}\n {renderedItems.map(renderItem)}\n </Flex>\n </Modal>\n );\n};\n",".body {\n margin-bottom: 1rem;\n}\n\n.description {\n margin: 1rem 0 0.5rem;\n font-size: 1rem;\n line-height: 1.5;\n}\n\n.item {\n padding: 0.5rem;\n color: #6b7280;\n background: #f3f4f6;\n border-radius: 0.375rem;\n}\n\n:global(.dark) .item,\n:global([data-theme=\"dark\"]) .item {\n color: #e5e7eb;\n background: #262626;\n}\n\n.itemLabel {\n color: inherit;\n white-space: nowrap;\n}\n\n.itemValue {\n min-width: 0;\n overflow: hidden;\n text-align: right;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.link {\n color: inherit;\n text-decoration: none;\n}\n\n.poweredBy {\n color: #6b7280;\n}\n\n:global(.dark) .poweredBy,\n:global([data-theme=\"dark\"]) .poweredBy {\n color: #e5e7eb;\n}\n",".root {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.sidebar {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n overflow: hidden;\n transition: width 200ms ease;\n}\n\n.sidebarTop,\n.sidebarBottom {\n flex-shrink: 0;\n}\n\n.sidebarList {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n}\n\n.desktopArea {\n flex-grow: 1;\n min-width: 0;\n height: 100%;\n overflow: hidden;\n transition: width 200ms ease;\n}\n\n.content {\n height: calc(100% - var(--cube-header-height, 3rem) - 1px);\n overflow-y: auto;\n}\n\n.searchButton {\n width: 15rem;\n}\n\n.mobileRoot {\n width: 100vw;\n height: 100%;\n overflow: hidden;\n}\n\n.mobileContent {\n width: 100%;\n height: 100%;\n overflow-y: auto;\n}\n","import { Fragment, type ReactNode } from \"react\";\nimport { Button, Drawer, Flex, Statistic } from \"antd\";\nimport { useCubeAppContext } from \"../cube-app/cube-app\";\nimport styles from \"./mobile-account-sheet.module.css\";\n\nexport interface MobileAccountSheetProps {\n visible: boolean;\n onVisibleChange(visible: boolean): void;\n}\n\ninterface CellProps {\n title: ReactNode;\n extra?: ReactNode;\n onClick?(): void;\n}\n\nconst Cell = ({ title, extra, onClick }: CellProps) =>\n onClick ? (\n <button type=\"button\" className={styles.cell} onClick={onClick}>\n <span>{title}</span>\n {extra ? <span>{extra}</span> : null}\n </button>\n ) : (\n <div className={styles.cell}>\n <span>{title}</span>\n {extra ? <span>{extra}</span> : null}\n </div>\n );\n\nexport const MobileAccountSheet = ({ visible, onVisibleChange }: MobileAccountSheetProps) => {\n const { accountMenuStats, accountMenuItems, onLogoutBtnClick, userName } = useCubeAppContext();\n const close = () => onVisibleChange(false);\n\n return (\n <Drawer\n open={visible}\n onClose={close}\n placement=\"left\"\n width=\"100%\"\n closable={false}\n styles={{\n header: { display: \"none\" },\n body: { padding: 12 },\n footer: { padding: 8, borderTop: \"none\" },\n }}\n footer={\n <Button block size=\"large\" type=\"primary\" aria-label=\"返回\" onClick={close}>\n 返回\n </Button>\n }\n >\n <Flex vertical gap={12}>\n {accountMenuStats && accountMenuStats.length > 0 ? (\n <div className={styles.card}>\n <Flex justify=\"space-around\">\n {accountMenuStats.map((stat) => (\n <Statistic key={stat.key} title={stat.title} value={stat.value} prefix={stat.icon} />\n ))}\n </Flex>\n </div>\n ) : null}\n\n {userName ? (\n <div className={styles.card}>\n <Cell title=\"登录用户\" extra={userName} />\n </div>\n ) : null}\n\n {accountMenuItems && accountMenuItems.length > 0 ? (\n <div className={styles.card}>\n {accountMenuItems.map((item, index) => (\n <Fragment key={item.key}>\n <Cell\n title={\n <>\n {item.icon} &nbsp;{item.label}\n </>\n }\n onClick={() => {\n item.onClick?.();\n close();\n }}\n />\n {index !== accountMenuItems.length - 1 ? <div className={styles.splitLine} /> : null}\n </Fragment>\n ))}\n </div>\n ) : null}\n\n {onLogoutBtnClick ? (\n <div className={styles.card}>\n <Cell\n title=\"登出\"\n onClick={() => {\n onLogoutBtnClick();\n close();\n }}\n />\n </div>\n ) : null}\n </Flex>\n </Drawer>\n );\n};\n",".card {\n padding: 0.5rem 0.75rem;\n background: var(--cube-surface-color, #fff);\n border: 1px solid var(--cube-border-color, #d1d5db);\n border-radius: 0.5rem;\n}\n\n:global(.dark) .card,\n:global([data-theme=\"dark\"]) .card {\n background: var(--cube-dark-surface-color, #141414);\n border-color: var(--cube-dark-border-color, #374151);\n}\n\n.cell {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 0.375rem 0;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n\n.splitLine {\n height: 1px;\n margin: 0.25rem 0;\n background: var(--cube-border-color, #d1d5db);\n}\n\n:global(.dark) .splitLine,\n:global([data-theme=\"dark\"]) .splitLine {\n background: var(--cube-dark-border-color, #374151);\n}\n","import { type HTMLAttributes, useEffect, useState } from \"react\";\nimport { Flex } from \"antd\";\nimport styles from \"./loading.module.css\";\n\nexport interface PageLoadingProps {\n tip?: string;\n}\n\nexport const PageLoading = ({ tip = \"加载中...\" }: PageLoadingProps) => (\n <Flex justify=\"center\" align=\"center\" className={styles.pageLoading}>\n {tip}\n </Flex>\n);\n\nexport interface DelayedLoadingProps extends HTMLAttributes<HTMLDivElement> {\n tip?: string;\n delay?: number;\n}\n\nexport const DelayedLoading = ({\n tip = \"页面加载中...\",\n delay = 500,\n className,\n ...props\n}: DelayedLoadingProps) => {\n const [visible, setVisible] = useState(false);\n\n useEffect(() => {\n const timer = window.setTimeout(() => setVisible(true), delay);\n return () => window.clearTimeout(timer);\n }, [delay]);\n\n if (!visible) return null;\n\n return (\n <div\n className={[styles.delayedLoading, className].filter(Boolean).join(\" \")}\n {...props}\n >\n {tip}\n </div>\n );\n};\n",".pageLoading {\n width: 100%;\n height: 100%;\n}\n\n.delayedLoading {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n margin: 1.5rem 0;\n}\n\n:global(.dark) .delayedLoading,\n:global([data-theme=\"dark\"]) .delayedLoading {\n color: #9ca3af;\n}\n","import type { PropsWithChildren, ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"antd\";\nimport { useCubeAppHeaderLeft } from \"../cube-app/cube-app\";\nimport { MobileOnly } from \"../responsive/responsive\";\nimport styles from \"./page.module.css\";\n\nconst PageContainer = ({ children }: PropsWithChildren) => <div className={styles.container}>{children}</div>;\n\nconst PageContent = ({ children }: PropsWithChildren) => <div className={styles.content}>{children}</div>;\n\nconst PageActionBar = ({ children }: PropsWithChildren) => (\n <MobileOnly>\n <div className={styles.actionBar}>{children}</div>\n </MobileOnly>\n);\n\nexport const ActionIcon = ({ className, size = \"large\", ...props }: ButtonProps) => (\n <Button className={[styles.actionIcon, className].filter(Boolean).join(\" \")} size={size} {...props} />\n);\n\nexport const ActionButton = ({\n children,\n type = \"primary\",\n block = true,\n size = \"large\",\n ...props\n}: ButtonProps) => (\n <Button block={block} size={size} type={type} {...props}>\n {children}\n </Button>\n);\n\nexport interface CubePageProps extends PropsWithChildren {\n desktopHeaderLeft?: ReactNode;\n mobileActionBar?: ReactNode;\n}\n\nexport const CubePage = ({ desktopHeaderLeft, mobileActionBar, children }: CubePageProps) => {\n useCubeAppHeaderLeft(desktopHeaderLeft);\n\n return (\n <PageContainer>\n <PageContent>{children}</PageContent>\n {mobileActionBar ? <PageActionBar>{mobileActionBar}</PageActionBar> : null}\n </PageContainer>\n );\n};\n",".container {\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.content {\n position: relative;\n height: 100%;\n overflow-y: auto;\n}\n\n@media (max-width: 767px) {\n .content {\n height: calc(100% - var(--cube-mobile-action-height, 40px) - 1rem);\n }\n}\n\n.actionBar {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 0.5rem;\n height: var(--cube-mobile-action-height, 40px);\n padding: 0.5rem;\n}\n\n.actionIcon {\n flex-shrink: 0;\n}\n"],"mappings":"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","names":["useMemo","useMemo","useCallback","useMemo","useState","Button","jsx","jsx","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","useState","useCallback","useMemo","Button","Fragment","Button","Flex","Statistic","Fragment","jsx","jsxs","Button","Flex","Statistic","useEffect","useState","Flex","jsx","Flex","useState","useEffect","Button","jsx","jsxs","Button"]}
1
+ {"version":3,"sources":["../src/responsive/responsive.tsx","../src/cube-config-provider/cube-config-provider.tsx","../src/cube-app/cube-app.tsx","../src/app-header/app-header.tsx","../src/account-menu/account-menu-button.tsx","../src/account-menu/account-menu.tsx","../src/about-dialog/about-dialog.tsx","../src/mobile-account-sheet/mobile-account-sheet.tsx","../src/loading/loading.tsx","../src/page/page.tsx","../src/empty-tip/empty-tip.tsx","../src/color-list/color-list.tsx","../src/search-page/search-page.tsx"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, useCallback, useMemo, useSyncExternalStore } from \"react\";\n\nexport const DEFAULT_MOBILE_BREAKPOINT = 767;\n\nexport interface UseMediaQueryOptions {\n defaultMatches?: boolean;\n}\n\nexport interface ResponsiveProps extends PropsWithChildren {\n defaultMatches?: boolean;\n}\n\nexport const useMediaQuery = (query: string, options: UseMediaQueryOptions = {}): boolean => {\n const { defaultMatches = false } = options;\n const mediaQueryList = useMemo(\n () =>\n typeof window !== \"undefined\" && typeof window.matchMedia === \"function\"\n ? window.matchMedia(query)\n : null,\n [query],\n );\n\n const subscribe = useCallback(\n (notify: () => void) => {\n if (!mediaQueryList) return () => undefined;\n mediaQueryList.addEventListener(\"change\", notify);\n return () => mediaQueryList.removeEventListener(\"change\", notify);\n },\n [mediaQueryList],\n );\n\n const getSnapshot = useCallback(\n () => mediaQueryList?.matches ?? defaultMatches,\n [defaultMatches, mediaQueryList],\n );\n const getServerSnapshot = useCallback(() => defaultMatches, [defaultMatches]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n};\n\nexport const useIsMobile = ({ defaultMatches }: UseMediaQueryOptions = {}): boolean =>\n useMediaQuery(`(max-width: ${DEFAULT_MOBILE_BREAKPOINT}px)`, { defaultMatches });\n\nexport const MobileOnly = ({ children, defaultMatches }: ResponsiveProps): ReactNode => {\n const isMobile = useIsMobile({ defaultMatches });\n return isMobile ? children : null;\n};\n\nexport const DesktopOnly = ({ children, defaultMatches }: ResponsiveProps): ReactNode => {\n const isMobile = useIsMobile({ defaultMatches });\n return isMobile ? null : children;\n};\n","import { useMemo, type ReactNode } from \"react\";\nimport { ConfigProvider } from \"antd\";\nimport zhCN from \"antd/locale/zh_CN\";\nimport { useIsMobile } from \"../responsive/responsive\";\n\nexport interface CubeConfigProviderProps {\n children: ReactNode;\n\n primaryColor?: string;\n}\n\nconst DEFAULT_PRIMARY_COLOR = \"#ec008c\";\n\n/**\n * Applies the fixed Cube antd configuration (`zh_CN` locale, `primaryColor` token, a larger\n * base font size on mobile) without rendering any application shell. Mount it on its own for\n * pages that should share the Cube theme but live outside `CubeApp` — `CubeApp` itself wraps\n * this component internally.\n */\nexport const CubeConfigProvider = ({ children, primaryColor }: CubeConfigProviderProps) => {\n const isMobile = useIsMobile();\n\n const theme = useMemo(\n () => ({\n token: {\n colorPrimary: primaryColor ?? DEFAULT_PRIMARY_COLOR,\n lineWidth: 2,\n controlOutlineWidth: 1,\n ...(isMobile ? { fontSize: 16 } : {}),\n },\n components: {\n Card: {\n colorBorderSecondary: \"var(--cube-border-color, #d1d5db)\",\n lineHeight: 1.6,\n },\n },\n }),\n [primaryColor, isMobile],\n );\n\n return (\n <ConfigProvider locale={zhCN} theme={theme}>\n {children}\n </ConfigProvider>\n );\n};\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { Button } from \"antd\";\nimport { SearchOutlined, SmileOutlined } from \"@ant-design/icons\";\nimport { useIsMobile } from \"../responsive/responsive\";\nimport { CubeConfigProvider } from \"../cube-config-provider/cube-config-provider\";\nimport { AppHeader } from \"../app-header/app-header\";\nimport { AccountMenuButton } from \"../account-menu/account-menu-button\";\nimport { AccountMenu, type AccountMenuItem, type AccountMenuStat } from \"../account-menu/account-menu\";\nimport {\n AboutDialog,\n type AboutAppInfo,\n type AboutAuthorInfo,\n type AboutItem,\n} from \"../about-dialog/about-dialog\";\nimport \"./cube-app.css\";\n\nexport interface CubeAppAboutInfo extends AboutAppInfo {\n contactEmail?: string;\n author?: AboutAuthorInfo;\n items?: AboutItem[];\n}\n\nexport interface CubeAppContextValue {\n accountMenuStats?: AccountMenuStat[];\n accountMenuItems?: AccountMenuItem[];\n onLogoutBtnClick?(): void;\n userName?: ReactNode;\n openAbout(): void;\n setHeaderLeft(node: ReactNode): void;\n}\n\nconst CubeAppContext = createContext<CubeAppContextValue>({\n openAbout: () => undefined,\n setHeaderLeft: () => undefined,\n});\n\n/**\n * Reads the account/about configuration passed to `CubeApp`. Only needed by components\n * mounted elsewhere in the route tree (e.g. `MobileAccountSheet`) — `CubeApp` itself\n * already has this data as props.\n */\nexport const useCubeAppContext = (): CubeAppContextValue => useContext(CubeAppContext);\n\n/**\n * Lets the currently mounted page override `CubeApp`'s `headerLeft` slot. Resets to the\n * default `headerLeft` prop when the calling component unmounts.\n */\nexport const useCubeAppHeaderLeft = (node: ReactNode): void => {\n const { setHeaderLeft } = useCubeAppContext();\n\n useEffect(() => {\n setHeaderLeft(node);\n return () => setHeaderLeft(undefined);\n }, [node, setHeaderLeft]);\n};\n\nexport interface CubeAppProps {\n children: ReactNode;\n\n primaryColor?: string;\n\n accountMenuStats?: AccountMenuStat[];\n accountMenuItems?: AccountMenuItem[];\n onLogoutBtnClick?(): void;\n userName?: ReactNode;\n about: CubeAppAboutInfo;\n\n sidebarTop?: ReactNode;\n sidebarList?: ReactNode;\n sidebarBottom?: ReactNode;\n\n headerLeft?: ReactNode;\n headerRight?: ReactNode;\n headerSearchBtnLabel?: string;\n onHeaderSearchBtnClick?(): void;\n}\n\nconst SIDEBAR_WIDTH = \"var(--cube-sidebar-width, 15rem)\";\n\nexport const CubeApp = ({\n children,\n primaryColor,\n accountMenuStats,\n accountMenuItems,\n onLogoutBtnClick,\n userName,\n about,\n sidebarTop,\n sidebarList,\n sidebarBottom,\n headerLeft,\n headerRight,\n headerSearchBtnLabel,\n onHeaderSearchBtnClick,\n}: CubeAppProps) => {\n const isMobile = useIsMobile();\n const [collapsed, setCollapsed] = useState(false);\n const toggleSidebar = useCallback(() => setCollapsed((value) => !value), []);\n const [aboutOpen, setAboutOpen] = useState(false);\n const [headerLeftOverride, setHeaderLeftOverride] = useState<ReactNode>(undefined);\n\n const itemsWithAbout = useMemo<AccountMenuItem[]>(\n () => [\n ...(accountMenuItems ?? []),\n {\n key: \"cube-app-about\",\n label: \"关于\",\n icon: <SmileOutlined />,\n onClick: () => setAboutOpen(true),\n },\n ],\n [accountMenuItems],\n );\n\n const contextValue = useMemo<CubeAppContextValue>(\n () => ({\n accountMenuStats,\n accountMenuItems: itemsWithAbout,\n onLogoutBtnClick,\n userName,\n openAbout: () => setAboutOpen(true),\n setHeaderLeft: setHeaderLeftOverride,\n }),\n [accountMenuStats, itemsWithAbout, onLogoutBtnClick, userName],\n );\n\n const renderAccountMenuButton = () => (\n <AccountMenuButton\n content={({ close }) => (\n <AccountMenu\n stats={accountMenuStats}\n items={itemsWithAbout.map((item) => ({\n ...item,\n onClick: () => {\n item.onClick?.();\n close();\n },\n }))}\n footer={\n onLogoutBtnClick ? (\n <Button\n block\n danger\n aria-label=\"登出\"\n onClick={() => {\n onLogoutBtnClick();\n close();\n }}\n >\n 登出\n </Button>\n ) : undefined\n }\n />\n )}\n />\n );\n\n const renderShell = () => {\n if (isMobile) {\n return (\n <div className={\"cube-app-mobile-root\"} data-testid=\"cube-app-shell-mobile\">\n <main className={\"cube-app-mobile-content\"}>{children}</main>\n </div>\n );\n }\n\n const sidebarStyle: CSSProperties = {\n width: collapsed ? \"0px\" : SIDEBAR_WIDTH,\n };\n const contentStyle: CSSProperties = {\n width: collapsed ? \"100vw\" : `calc(100vw - ${SIDEBAR_WIDTH})`,\n };\n\n return (\n <div className={\"cube-app-root\"} data-testid=\"cube-app-shell\">\n <aside\n className={\"cube-app-sidebar\"}\n style={sidebarStyle}\n data-testid=\"cube-app-shell-sidebar\"\n aria-hidden={collapsed}\n >\n {sidebarTop ? <div className={\"cube-app-sidebar-top\"}>{sidebarTop}</div> : null}\n <div className={\"cube-app-sidebar-list\"}>{sidebarList}</div>\n {sidebarBottom ? <div className={\"cube-app-sidebar-bottom\"}>{sidebarBottom}</div> : null}\n </aside>\n <div className={\"cube-app-desktop-area\"} style={contentStyle}>\n <AppHeader\n title={headerLeftOverride ?? headerLeft}\n collapsed={collapsed}\n onToggleSidebar={toggleSidebar}\n actions={\n <>\n {headerRight}\n {onHeaderSearchBtnClick ? (\n <Button\n className={\"cube-app-search-button\"}\n icon={<SearchOutlined aria-hidden />}\n aria-label={headerSearchBtnLabel ?? \"\\u641c\\u7d22\"}\n onClick={onHeaderSearchBtnClick}\n >\n {headerSearchBtnLabel ?? \"\\u641c\\u7d22\"}\n </Button>\n ) : null}\n {renderAccountMenuButton()}\n </>\n }\n />\n <main className={\"cube-app-content\"}>{children}</main>\n </div>\n </div>\n );\n };\n\n return (\n <CubeConfigProvider primaryColor={primaryColor}>\n <CubeAppContext.Provider value={contextValue}>\n {renderShell()}\n <AboutDialog\n open={aboutOpen}\n onClose={() => setAboutOpen(false)}\n app={about}\n contactEmail={about.contactEmail}\n author={about.author}\n items={about.items}\n />\n </CubeAppContext.Provider>\n </CubeConfigProvider>\n );\n};\n","import type { HTMLAttributes, ReactNode } from \"react\";\nimport { MenuFoldOutlined, MenuUnfoldOutlined } from \"@ant-design/icons\";\nimport \"./app-header.css\";\n\nexport interface AppHeaderProps extends Omit<HTMLAttributes<HTMLElement>, \"title\"> {\n title?: ReactNode;\n actions?: ReactNode;\n collapsed?: boolean;\n showSidebarToggle?: boolean;\n onToggleSidebar?(): void;\n}\n\nexport const AppHeader = ({\n title,\n actions,\n collapsed = false,\n onToggleSidebar,\n showSidebarToggle = onToggleSidebar !== undefined,\n className,\n ...headerProps\n}: AppHeaderProps) => {\n const label = collapsed ? \"展开侧边栏\" : \"收起侧边栏\";\n const ToggleIcon = collapsed ? MenuUnfoldOutlined : MenuFoldOutlined;\n\n return (\n <header className={[\"cube-app-header\", className].filter(Boolean).join(\" \")} {...headerProps}>\n <div className={\"cube-app-header-leading\"}>\n {showSidebarToggle ? (\n <button\n type=\"button\"\n className={\"cube-app-header-toggle\"}\n aria-label={label}\n aria-expanded={!collapsed}\n onClick={onToggleSidebar}\n >\n <ToggleIcon aria-hidden />\n </button>\n ) : null}\n <div className={\"cube-app-header-title\"}>{title}</div>\n </div>\n {actions ? <div className={\"cube-app-header-actions\"}>{actions}</div> : null}\n </header>\n );\n};\n","import { type ReactNode, useState } from \"react\";\nimport { UserOutlined } from \"@ant-design/icons\";\nimport { Popover } from \"antd\";\nimport \"./account-menu.css\";\n\nexport interface AccountMenuRenderContext {\n close(): void;\n}\n\nexport interface AccountMenuButtonProps {\n content: ReactNode | ((context: AccountMenuRenderContext) => ReactNode);\n}\n\nexport const AccountMenuButton = ({ content }: AccountMenuButtonProps) => {\n const [open, setOpen] = useState(false);\n const close = () => setOpen(false);\n const renderedContent = typeof content === \"function\" ? content({ close }) : content;\n\n return (\n <Popover\n placement=\"bottomRight\"\n trigger=\"click\"\n content={renderedContent}\n open={open}\n onOpenChange={setOpen}\n arrow\n >\n <button\n type=\"button\"\n className={\"cube-account-trigger\"}\n aria-label=\"打开用户菜单\"\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n >\n <UserOutlined aria-hidden />\n </button>\n </Popover>\n );\n};\n","import type { Key, ReactNode } from \"react\";\nimport { Button, Statistic } from \"antd\";\nimport \"./account-menu.css\";\n\nexport interface AccountMenuStat {\n key: Key;\n title: ReactNode;\n value: string | number;\n icon?: ReactNode;\n}\n\nexport interface AccountMenuItem {\n key: Key;\n label: ReactNode;\n icon?: ReactNode;\n danger?: boolean;\n disabled?: boolean;\n onClick?(): void;\n}\n\nexport interface AccountMenuProps {\n stats?: AccountMenuStat[];\n items?: AccountMenuItem[];\n footer?: ReactNode;\n}\n\nexport const AccountMenu = ({ stats = [], items = [], footer }: AccountMenuProps) => (\n <div className={\"cube-account-menu\"}>\n {stats.length > 0 ? (\n <div className={\"cube-account-menu-stats\"}>\n {stats.map((stat) => (\n <Statistic key={stat.key} title={stat.title} value={stat.value} prefix={stat.icon} />\n ))}\n </div>\n ) : null}\n {items.length > 0 ? (\n <div className={\"cube-account-menu-items\"}>\n {items.map((item) => (\n <Button\n key={item.key}\n block\n icon={item.icon}\n danger={item.danger}\n disabled={item.disabled}\n aria-label={typeof item.label === \"string\" ? item.label : undefined}\n onClick={item.onClick}\n >\n {item.label}\n </Button>\n ))}\n </div>\n ) : null}\n {footer ? <div className={\"cube-account-menu-footer\"}>{footer}</div> : null}\n </div>\n);\n","import type { Key, ReactNode } from \"react\";\nimport { BarcodeOutlined, GithubOutlined, SendOutlined } from \"@ant-design/icons\";\nimport { Flex, Modal } from \"antd\";\nimport \"./about-dialog.css\";\n\nexport interface AboutAppInfo {\n name: string;\n version?: string;\n repository?: string;\n description?: ReactNode;\n}\n\nexport interface AboutAuthorInfo {\n name: string;\n url?: string;\n}\n\nexport interface AboutItem {\n key: Key;\n icon?: ReactNode;\n label: ReactNode;\n value: ReactNode;\n href?: string;\n}\n\nexport interface AboutDialogProps {\n open: boolean;\n onClose(): void;\n app: AboutAppInfo;\n contactEmail?: string;\n author?: AboutAuthorInfo;\n items?: AboutItem[];\n}\n\nconst renderItem = (item: AboutItem) => {\n const content = (\n <div className={\"cube-about-item\"}>\n <Flex justify=\"space-between\" gap={16}>\n <div className={\"cube-about-item-label\"}>\n {item.icon ? <>{item.icon} &nbsp;</> : null}\n {item.label}\n </div>\n <div className={\"cube-about-item-value\"}>{item.value}</div>\n </Flex>\n </div>\n );\n\n return item.href ? (\n <a key={item.key} href={item.href} className={\"cube-about-link\"}>\n {content}\n </a>\n ) : (\n <div key={item.key}>{content}</div>\n );\n};\n\nexport const AboutDialog = ({\n open,\n onClose,\n app,\n contactEmail,\n author,\n items = [],\n}: AboutDialogProps) => {\n const defaultItems: AboutItem[] = [];\n\n if (contactEmail) {\n defaultItems.push({\n key: \"contact\",\n icon: <SendOutlined />,\n label: \"联系我\",\n value: contactEmail,\n href: `mailto:${contactEmail}?&subject=${encodeURIComponent(\n `${app.name} 相关`,\n )}`,\n });\n }\n\n if (app.version) {\n defaultItems.push({\n key: \"version\",\n icon: <BarcodeOutlined />,\n label: \"当前版本\",\n value: app.version,\n });\n }\n\n if (app.repository) {\n defaultItems.push({\n key: \"repository\",\n icon: <GithubOutlined />,\n label: \"开源地址\",\n value: \"github\",\n href: app.repository,\n });\n }\n\n const renderedItems = [...defaultItems, ...items];\n\n return (\n <Modal\n open={open}\n onCancel={onClose}\n onOk={onClose}\n title={`关于应用 ${app.name}`}\n footer={(_, { OkBtn }) => (\n <Flex\n align=\"center\"\n justify={author ? \"space-between\" : \"flex-end\"}\n gap={16}\n >\n {author ? (\n <div className={\"cube-about-powered-by\"}>\n Powered by 💗{\" \"}\n {author.url ? (\n <a href={author.url}>{author.name}</a>\n ) : (\n author.name\n )}\n </div>\n ) : null}\n <OkBtn />\n </Flex>\n )}\n >\n <Flex gap={16} vertical className={\"cube-about-body\"}>\n {app.description ? (\n <div className={\"cube-about-description\"}>{app.description}</div>\n ) : null}\n {renderedItems.map(renderItem)}\n </Flex>\n </Modal>\n );\n};\n","import { Fragment, type ReactNode } from \"react\";\nimport { Button, Drawer, Flex, Statistic } from \"antd\";\nimport { useCubeAppContext } from \"../cube-app/cube-app\";\nimport \"./mobile-account-sheet.css\";\n\nexport interface MobileAccountSheetProps {\n visible: boolean;\n onVisibleChange(visible: boolean): void;\n}\n\ninterface CellProps {\n title: ReactNode;\n extra?: ReactNode;\n onClick?(): void;\n}\n\nconst Cell = ({ title, extra, onClick }: CellProps) =>\n onClick ? (\n <button type=\"button\" className={\"cube-sheet-cell\"} onClick={onClick}>\n <span>{title}</span>\n {extra ? <span>{extra}</span> : null}\n </button>\n ) : (\n <div className={\"cube-sheet-cell\"}>\n <span>{title}</span>\n {extra ? <span>{extra}</span> : null}\n </div>\n );\n\nexport const MobileAccountSheet = ({ visible, onVisibleChange }: MobileAccountSheetProps) => {\n const { accountMenuStats, accountMenuItems, onLogoutBtnClick, userName } = useCubeAppContext();\n const close = () => onVisibleChange(false);\n\n return (\n <Drawer\n open={visible}\n onClose={close}\n placement=\"left\"\n width=\"100%\"\n closable={false}\n styles={{\n header: { display: \"none\" },\n body: { padding: 12 },\n footer: { padding: 8, borderTop: \"none\" },\n }}\n footer={\n <Button block size=\"large\" type=\"primary\" aria-label=\"返回\" onClick={close}>\n 返回\n </Button>\n }\n >\n <Flex vertical gap={12}>\n {accountMenuStats && accountMenuStats.length > 0 ? (\n <div className={\"cube-sheet-card\"}>\n <Flex justify=\"space-around\">\n {accountMenuStats.map((stat) => (\n <Statistic key={stat.key} title={stat.title} value={stat.value} prefix={stat.icon} />\n ))}\n </Flex>\n </div>\n ) : null}\n\n {userName ? (\n <div className={\"cube-sheet-card\"}>\n <Cell title=\"登录用户\" extra={userName} />\n </div>\n ) : null}\n\n {accountMenuItems && accountMenuItems.length > 0 ? (\n <div className={\"cube-sheet-card\"}>\n {accountMenuItems.map((item, index) => (\n <Fragment key={item.key}>\n <Cell\n title={\n <>\n {item.icon} &nbsp;{item.label}\n </>\n }\n onClick={() => {\n item.onClick?.();\n close();\n }}\n />\n {index !== accountMenuItems.length - 1 ? <div className={\"cube-sheet-split-line\"} /> : null}\n </Fragment>\n ))}\n </div>\n ) : null}\n\n {onLogoutBtnClick ? (\n <div className={\"cube-sheet-card\"}>\n <Cell\n title=\"登出\"\n onClick={() => {\n onLogoutBtnClick();\n close();\n }}\n />\n </div>\n ) : null}\n </Flex>\n </Drawer>\n );\n};\n","import { type HTMLAttributes, useEffect, useState } from \"react\";\nimport { Flex } from \"antd\";\nimport \"./loading.css\";\n\nexport interface PageLoadingProps {\n tip?: string;\n}\n\nexport const PageLoading = ({ tip = \"加载中...\" }: PageLoadingProps) => (\n <Flex justify=\"center\" align=\"center\" className={\"cube-page-loading\"}>\n {tip}\n </Flex>\n);\n\nexport interface DelayedLoadingProps extends HTMLAttributes<HTMLDivElement> {\n tip?: string;\n delay?: number;\n}\n\nexport const DelayedLoading = ({\n tip = \"页面加载中...\",\n delay = 500,\n className,\n ...props\n}: DelayedLoadingProps) => {\n const [visible, setVisible] = useState(false);\n\n useEffect(() => {\n const timer = window.setTimeout(() => setVisible(true), delay);\n return () => window.clearTimeout(timer);\n }, [delay]);\n\n if (!visible) return null;\n\n return (\n <div\n className={[\"cube-delayed-loading\", className].filter(Boolean).join(\" \")}\n {...props}\n >\n {tip}\n </div>\n );\n};\n","import type { PropsWithChildren, ReactNode } from \"react\";\nimport { Button, Input, type ButtonProps } from \"antd\";\nimport type { SearchProps } from \"antd/es/input\";\nimport { SearchOutlined } from \"@ant-design/icons\";\nimport { useCubeAppHeaderLeft } from \"../cube-app/cube-app\";\nimport { MobileOnly } from \"../responsive/responsive\";\nimport \"./page.css\";\n\nconst PageContainer = ({ children }: PropsWithChildren) => <div className={\"cube-page-container\"}>{children}</div>;\n\nconst PageContent = ({ children }: PropsWithChildren) => <div className={\"cube-page-content\"}>{children}</div>;\n\nconst PageActionBar = ({ children }: PropsWithChildren) => (\n <MobileOnly>\n <div className={\"cube-page-action-bar\"}>{children}</div>\n </MobileOnly>\n);\n\nexport const ActionIcon = ({ className, size = \"large\", ...props }: ButtonProps) => (\n <Button className={[\"cube-page-action-icon\", className].filter(Boolean).join(\" \")} size={size} {...props} />\n);\n\nexport const ActionButton = ({\n children,\n type = \"primary\",\n block = true,\n size = \"large\",\n ...props\n}: ButtonProps) => (\n <Button block={block} size={size} type={type} {...props}>\n {children}\n </Button>\n);\n\n/** Mobile action-bar search field (fills remaining width). */\nexport const ActionSearch = ({ className, ...props }: SearchProps) => (\n <Input.Search\n placeholder=\"输入关键字搜索\"\n enterButton={<SearchOutlined />}\n size=\"large\"\n autoFocus\n {...props}\n className={[\"cube-page-action-search\", className].filter(Boolean).join(\" \")}\n />\n);\n\nexport interface CubePageProps extends PropsWithChildren {\n desktopHeaderLeft?: ReactNode;\n mobileActionBar?: ReactNode;\n}\n\nexport const CubePage = ({ desktopHeaderLeft, mobileActionBar, children }: CubePageProps) => {\n useCubeAppHeaderLeft(desktopHeaderLeft);\n\n return (\n <PageContainer>\n <PageContent>{children}</PageContent>\n {mobileActionBar ? <PageActionBar>{mobileActionBar}</PageActionBar> : null}\n </PageContainer>\n );\n};\n","import type { ReactNode } from \"react\";\nimport { Flex } from \"antd\";\nimport \"./empty-tip.css\";\n\nexport interface EmptyTipProps {\n className?: string;\n title?: ReactNode;\n subTitle?: ReactNode;\n extra?: ReactNode;\n}\n\nexport const EmptyTip = ({ title, subTitle, extra, className }: EmptyTipProps) => (\n <Flex\n vertical\n gap={4}\n align=\"center\"\n justify=\"center\"\n className={[\"cube-empty-tip\", className].filter(Boolean).join(\" \")}\n >\n {title ? <div className=\"cube-empty-tip-title\">{title}</div> : null}\n {subTitle ? <div className=\"cube-empty-tip-subtitle\">{subTitle}</div> : null}\n {extra ? <div>{extra}</div> : null}\n </Flex>\n);\n","import { Flex, type FlexProps } from \"antd\";\nimport \"./color-list.css\";\n\nexport const MARK_COLORS_MAP: Record<string, string> = {\n c1: \"#ef4444\",\n c2: \"#f97316\",\n c3: \"#f59e0b\",\n c4: \"#eab308\",\n c5: \"#84cc16\",\n c6: \"#22c55e\",\n c7: \"#10b981\",\n c8: \"#14b8a6\",\n c9: \"#06b6d4\",\n c10: \"#0ea5e9\",\n c11: \"#3b82f6\",\n c12: \"#6366f1\",\n c13: \"#8b5cf6\",\n c14: \"#a855f7\",\n c15: \"#d946ef\",\n c16: \"#ec4899\",\n};\n\nexport const MARK_COLORS = [\n \"c1\",\n \"c2\",\n \"c3\",\n \"c4\",\n \"c5\",\n \"c6\",\n \"c7\",\n \"c8\",\n \"c9\",\n \"c10\",\n \"c11\",\n \"c12\",\n \"c13\",\n \"c14\",\n \"c15\",\n \"c16\",\n] as const;\n\nexport const MARK_COLORS_WITH_EMPTY = [...MARK_COLORS, \"\"] as const;\n\nexport const getColorValue = (colorCode: string): string | undefined => MARK_COLORS_MAP[colorCode];\n\ninterface ColorItemProps {\n colorCode: string;\n selected: boolean;\n onClick(colorCode: string): void;\n}\n\nconst ColorItem = ({ colorCode, selected, onClick }: ColorItemProps) => {\n const classes = [\"cube-color-dot\"];\n if (selected) classes.push(\"cube-color-dot-selected\");\n if (colorCode === \"\") classes.push(\"cube-color-dot-clear\");\n\n return (\n <button\n type=\"button\"\n aria-label={colorCode === \"\" ? \"清除颜色\" : `颜色 ${colorCode}`}\n className={classes.join(\" \")}\n style={{ backgroundColor: MARK_COLORS_MAP[colorCode] }}\n onClick={() => onClick(colorCode)}\n />\n );\n};\n\nexport interface ColorListProps {\n value?: string;\n onChange?(value: string): void;\n flexProps?: Omit<FlexProps, \"children\">;\n}\n\n/** Single-select color dots (includes a clear/empty option), matching Cube search filters. */\nexport const ColorList = ({ value, onChange, flexProps }: ColorListProps) => (\n <Flex wrap gap={8} {...flexProps}>\n {MARK_COLORS_WITH_EMPTY.map((colorCode) => (\n <ColorItem\n key={colorCode || \"clear\"}\n colorCode={colorCode}\n selected={value === colorCode}\n onClick={(next) => onChange?.(next)}\n />\n ))}\n </Flex>\n);\n","import { type ReactNode, useState } from \"react\";\nimport { Button, Col, Drawer, Flex, Input, Row } from \"antd\";\nimport { FilterOutlined, LeftOutlined } from \"@ant-design/icons\";\nimport { ActionIcon, ActionSearch, CubePage } from \"../page/page\";\nimport { DesktopOnly, MobileOnly } from \"../responsive/responsive\";\nimport { EmptyTip } from \"../empty-tip/empty-tip\";\nimport \"./search-page.css\";\n\nexport interface CubeSearchPageProps {\n /** Last committed keyword; used as the search inputs' default value. */\n keyword?: string;\n placeholder?: string;\n searchButtonLabel?: string;\n onSearch(value: string): void;\n onBack(): void;\n desktopHeaderLeft?: ReactNode;\n /** Filter UI (colors, tags, …). Desktop: in the page body. Mobile: in a bottom drawer. */\n filters?: ReactNode;\n mobileFilterTitle?: string;\n mobileFilterIcon?: ReactNode;\n /** True before the first search (no keyword / filters committed). */\n pending?: boolean;\n loading?: boolean;\n /** True after a search that returned no rows. Ignored while pending or loading. */\n empty?: boolean;\n pendingHint?: ReactNode;\n loadingTitle?: ReactNode;\n loadingHint?: ReactNode;\n emptyTitle?: ReactNode;\n emptyHint?: ReactNode;\n children?: ReactNode;\n}\n\nexport const CubeSearchPage = ({\n keyword = \"\",\n placeholder = \"请输入关键字,回车搜索\",\n searchButtonLabel = \"搜索\",\n onSearch,\n onBack,\n desktopHeaderLeft,\n filters,\n mobileFilterTitle = \"筛选\",\n mobileFilterIcon,\n pending = false,\n loading = false,\n empty = false,\n pendingHint = \"可使用关键词和颜色进行搜索\",\n loadingTitle = \"正在搜索中...\",\n loadingHint = \"请稍候\",\n emptyTitle = \"没有找到相关结果\",\n emptyHint = \"请尝试其他关键字\",\n children,\n}: CubeSearchPageProps) => {\n const [filterOpen, setFilterOpen] = useState(false);\n const hasFilters = filters != null;\n\n const renderBody = () => {\n if (loading) {\n return <EmptyTip title={loadingTitle} subTitle={loadingHint} />;\n }\n if (pending) {\n return <EmptyTip subTitle={pendingHint} />;\n }\n if (empty) {\n return (\n <div data-testid=\"search-empty-tip\">\n <EmptyTip title={emptyTitle} subTitle={emptyHint} />\n </div>\n );\n }\n\n return (\n <Flex\n vertical\n align=\"center\"\n gap={8}\n className=\"cube-search-page-results\"\n data-testid=\"search-result-list\"\n >\n {children}\n </Flex>\n );\n };\n\n return (\n <>\n <CubePage\n desktopHeaderLeft={desktopHeaderLeft}\n mobileActionBar={\n <>\n <ActionIcon icon={<LeftOutlined />} aria-label=\"返回\" onClick={onBack} />\n {hasFilters ? (\n <ActionIcon\n icon={mobileFilterIcon ?? <FilterOutlined />}\n aria-label=\"打开筛选\"\n onClick={() => setFilterOpen(true)}\n />\n ) : null}\n <ActionSearch defaultValue={keyword} onSearch={onSearch} />\n </>\n }\n >\n <Flex vertical gap={16} align=\"center\" className=\"cube-search-page\">\n <DesktopOnly>\n <Input.Search\n placeholder={placeholder}\n enterButton={searchButtonLabel}\n autoFocus\n size=\"large\"\n defaultValue={keyword}\n onSearch={onSearch}\n className=\"cube-search-page-input\"\n data-testid=\"search-keyword-input\"\n />\n </DesktopOnly>\n {hasFilters ? <DesktopOnly>{filters}</DesktopOnly> : null}\n {renderBody()}\n </Flex>\n </CubePage>\n\n {hasFilters ? (\n <MobileOnly>\n <Drawer\n title={mobileFilterTitle}\n open={filterOpen}\n onClose={() => setFilterOpen(false)}\n placement=\"bottom\"\n closable={false}\n styles={{\n footer: { padding: 8, border: \"none\" },\n header: { textAlign: \"center\", padding: 8 },\n }}\n footer={\n <Row gutter={8}>\n <Col flex=\"1\">\n <Button block size=\"large\" onClick={() => setFilterOpen(false)}>\n 确定\n </Button>\n </Col>\n </Row>\n }\n >\n <Flex vertical gap={16} className=\"cube-search-page-drawer\" align=\"center\">\n {filters}\n </Flex>\n </Drawer>\n </MobileOnly>\n ) : null}\n </>\n );\n};\n"],"mappings":"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","names":["useMemo","useMemo","useCallback","useMemo","useState","Button","jsx","jsx","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","useState","useCallback","useMemo","Button","Fragment","Button","Flex","Statistic","Fragment","jsx","jsxs","Button","Flex","Statistic","useEffect","useState","Flex","jsx","Flex","useState","useEffect","Button","SearchOutlined","jsx","jsxs","Button","SearchOutlined","Flex","jsx","jsxs","Flex","Flex","jsx","Flex","useState","Button","Drawer","Flex","Input","Fragment","jsx","jsxs","useState","Flex","Input","Drawer","Button"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hopgoldy/cube-ui",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Shared responsive application shell and UI primitives for Cube applications",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/HoPGoldy/cube-module#readme",