@svadmin/lite 0.22.2 → 0.23.1

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.
@@ -20,26 +20,26 @@
20
20
  const maxValue = $derived(Math.max(...data.map(d => d.value), 1));
21
21
  </script>
22
22
 
23
- <div class="lite-card" style="margin-bottom: 16px;">
23
+ <div class="lite-card lite-card-flush">
24
24
  {#if title}
25
- <div style="padding: 12px 16px; border-bottom: 1px solid #E5E6EB; font-weight: 600; font-size: 14px; color: #1D2129;">
26
- {title}
25
+ <div class="lite-card-header">
26
+ <h2 class="lite-card-title">{title}</h2>
27
27
  </div>
28
28
  {/if}
29
- <div class="lite-stack-md" style="padding: 16px;">
29
+ <div class="lite-card-body lite-stack-md">
30
30
  {#each data as point, _i (_i)}
31
31
  <div>
32
- <div style="display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 13px;">
33
- <span style="color: #1D2129;">{point.label}</span>
34
- <span style="color: #4E5969; font-weight: 500;">{point.value}</span>
32
+ <div class="lite-kv-row" style="margin-bottom: 4px; padding: 0;">
33
+ <span style="color: #334155;">{point.label}</span>
34
+ <span style="color: #425466; font-weight: 500;">{point.value}</span>
35
35
  </div>
36
- <div style="height: 20px; background: #F2F3F5; border-radius: 4px; overflow: hidden;">
37
- <div style="height: 100%; width: {(point.value / maxValue) * 100}%; background: {point.color ?? '#165DFF'}; border-radius: 4px; transition: width 0.3s;"></div>
36
+ <div style="height: 20px; background: #f1f4f8; border-radius: 4px; overflow: hidden;">
37
+ <div style="height: 100%; width: {(point.value / maxValue) * 100}%; background: {point.color ?? '#635bff'}; border-radius: 4px; transition: width 0.3s;"></div>
38
38
  </div>
39
39
  </div>
40
40
  {/each}
41
41
  {#if data.length === 0}
42
- <p style="color: #86909C; font-style: italic; text-align: center;">No data</p>
42
+ <p style="color: #94a3b8; font-style: italic; text-align: center; margin: 0;">No data</p>
43
43
  {/if}
44
44
  </div>
45
45
  </div>
@@ -19,17 +19,19 @@
19
19
  const renderedContent = $derived(renderRichContent(toSafeText(content), renderOptions));
20
20
  </script>
21
21
 
22
- <div class="lite-card lite-insight-card" style="margin-bottom: 16px;">
23
- <div class="lite-insight-card__header" style="padding: 12px 16px; border-bottom: 1px solid #E5E6EB; font-weight: 600; font-size: 14px; color: #1D2129;">
24
- <span style="color: #FF7D00;">✦</span>
25
- {title}
22
+ <div class="lite-card lite-card-flush">
23
+ <div class="lite-card-header">
24
+ <h2 class="lite-card-title lite-inline-xs" style="align-items: center;">
25
+ <span style="color: #d97706;">✦</span>
26
+ <span>{title}</span>
27
+ </h2>
26
28
  </div>
27
- <div class="lite-insight-card__body" style="padding: 16px; font-size: 14px; color: #1D2129; line-height: 1.6;">
29
+ <div class="lite-card-body" style="font-size: 14px; color: #334155; line-height: 1.6;">
28
30
  {#if renderedContent}
29
31
  <!-- eslint-disable-next-line svelte/no-at-html-tags -- 内容由 renderRichContent 转义或白名单过滤,高亮回调仅允许可信服务端实现。 -->
30
32
  <div class="lite-insight-content">{@html renderedContent}</div>
31
33
  {:else}
32
- <p style="color: #86909C; font-style: italic; margin: 0;">No insights available. AI analysis requires JavaScript.</p>
34
+ <p style="color: #94a3b8; font-style: italic; margin: 0;">No insights available. AI analysis requires JavaScript.</p>
33
35
  {/if}
34
36
  </div>
35
37
  </div>
@@ -20,32 +20,34 @@
20
20
  const rows = $derived(data.map((point) => [point.label, point.value] as [string, number]));
21
21
  </script>
22
22
 
23
- <div class="lite-card" style="margin-bottom: 16px;">
23
+ <div class="lite-card lite-card-flush">
24
24
  {#if title}
25
- <div style="padding: 12px 16px; border-bottom: 1px solid #E5E6EB; font-weight: 600; font-size: 14px; color: #1D2129;">
26
- {title}
25
+ <div class="lite-card-header">
26
+ <h2 class="lite-card-title">{title}</h2>
27
27
  </div>
28
28
  {/if}
29
29
  <LiteChartSvg kind="line" {rows} {title} />
30
- <table style="width: 100%; border-collapse: collapse;">
31
- <thead>
32
- <tr>
33
- <th style="text-align: left; padding: 10px 16px; font-size: 12px; color: #4E5969; border-bottom: 1px solid #E5E6EB;">Label</th>
34
- <th style="text-align: right; padding: 10px 16px; font-size: 12px; color: #4E5969; border-bottom: 1px solid #E5E6EB;">{valueLabel}</th>
35
- </tr>
36
- </thead>
37
- <tbody>
38
- {#each data as point, i (i)}
39
- <tr style="background: {i % 2 === 0 ? '#ffffff' : '#F7F8FA'};">
40
- <td style="padding: 8px 16px; font-size: 13px; color: #1D2129;">{point.label}</td>
41
- <td style="padding: 8px 16px; font-size: 13px; color: #1D2129; text-align: right; font-weight: 500;">{point.value}</td>
42
- </tr>
43
- {/each}
44
- {#if data.length === 0}
30
+ <div class="lite-table-scroll">
31
+ <table class="lite-table">
32
+ <thead>
45
33
  <tr>
46
- <td colspan="2" style="padding: 16px; text-align: center; color: #86909C; font-style: italic;">No data</td>
34
+ <th>Label</th>
35
+ <th style="text-align: right;">{valueLabel}</th>
47
36
  </tr>
48
- {/if}
49
- </tbody>
50
- </table>
37
+ </thead>
38
+ <tbody>
39
+ {#each data as point, i (i)}
40
+ <tr>
41
+ <td>{point.label}</td>
42
+ <td style="text-align: right; font-weight: 500;">{point.value}</td>
43
+ </tr>
44
+ {/each}
45
+ {#if data.length === 0}
46
+ <tr>
47
+ <td colspan="2" style="text-align: center; color: #94a3b8; font-style: italic;">No data</td>
48
+ </tr>
49
+ {/if}
50
+ </tbody>
51
+ </table>
52
+ </div>
51
53
  </div>
@@ -22,25 +22,25 @@
22
22
  const defaultColors = ['#165DFF', '#FF7D00', '#00B42A', '#F53F3F', '#8b5cf6', '#06b6d4', '#f97316', '#ec4899'];
23
23
  </script>
24
24
 
25
- <div class="lite-card" style="margin-bottom: 16px;">
25
+ <div class="lite-card lite-card-flush">
26
26
  {#if title}
27
- <div style="padding: 12px 16px; border-bottom: 1px solid #E5E6EB; font-weight: 600; font-size: 14px; color: #1D2129;">
28
- {title}
27
+ <div class="lite-card-header">
28
+ <h2 class="lite-card-title">{title}</h2>
29
29
  </div>
30
30
  {/if}
31
31
  <LiteChartSvg kind="pie" {rows} {title} />
32
- <div class="lite-stack-md" style="padding: 16px;">
32
+ <div class="lite-card-body lite-stack-md">
33
33
  {#each data as point, i (i)}
34
34
  {@const pct = total > 0 ? ((point.value / total) * 100).toFixed(1) : '0.0'}
35
35
  <div class="lite-inline-lg" style="align-items: center; font-size: 13px;">
36
36
  <span style="width: 12px; height: 12px; border-radius: 50%; background: {point.color ?? defaultColors[i % defaultColors.length]}; flex-shrink: 0;"></span>
37
- <span style="flex: 1; color: #1D2129;">{point.label}</span>
38
- <span style="color: #4E5969; font-weight: 500;">{point.value}</span>
39
- <span style="color: #86909C; font-size: 12px; min-width: 48px; text-align: right;">{pct}%</span>
37
+ <span style="flex: 1; color: #334155;">{point.label}</span>
38
+ <span style="color: #425466; font-weight: 500;">{point.value}</span>
39
+ <span style="color: #94a3b8; font-size: 12px; min-width: 48px; text-align: right;">{pct}%</span>
40
40
  </div>
41
41
  {/each}
42
42
  {#if data.length === 0}
43
- <p style="color: #86909C; font-style: italic; text-align: center;">No data</p>
43
+ <p style="color: #94a3b8; font-style: italic; text-align: center; margin: 0;">No data</p>
44
44
  {/if}
45
45
  </div>
46
46
  </div>
package/dist/lite.css CHANGED
@@ -251,6 +251,145 @@ a:hover {
251
251
  .lite-card[data-interactive="true"]:hover {
252
252
  box-shadow: 0 4px 12px -2px rgba(0, 0, 0, 0.08), 0 8px 24px -6px rgba(0, 0, 0, 0.04);
253
253
  }
254
+ .lite-card-flush {
255
+ padding: 0;
256
+ }
257
+ .lite-card-header {
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: space-between;
261
+ padding: 14px 16px;
262
+ border-bottom: 1px solid #e6ebf1;
263
+ }
264
+ .lite-card-header-start {
265
+ align-items: flex-start;
266
+ }
267
+ .lite-card-title {
268
+ margin: 0;
269
+ font-size: 15px;
270
+ line-height: 1.35;
271
+ font-weight: 600;
272
+ color: #0a2540;
273
+ }
274
+ .lite-card-subtitle {
275
+ margin: 4px 0 0;
276
+ font-size: 12px;
277
+ line-height: 1.4;
278
+ color: #425466;
279
+ }
280
+ .lite-card-body {
281
+ padding: 16px;
282
+ }
283
+ .lite-card-footer {
284
+ display: flex;
285
+ align-items: center;
286
+ justify-content: space-between;
287
+ padding: 12px 16px;
288
+ border-top: 1px solid #e6ebf1;
289
+ background: #fcfdfe;
290
+ border-bottom-left-radius: 7px;
291
+ border-bottom-right-radius: 7px;
292
+ }
293
+ .lite-card-action {
294
+ margin-left: 12px;
295
+ flex-shrink: 0;
296
+ }
297
+ .lite-card-flush > .lite-table,
298
+ .lite-card-flush > .lite-table-scroll > .lite-table {
299
+ border-left: none;
300
+ border-right: none;
301
+ border-bottom: none;
302
+ border-radius: 0;
303
+ }
304
+
305
+ /* ─── Key-Value Rows ───────────────────────────────────────── */
306
+ .lite-kv-list {
307
+ list-style: none;
308
+ margin: 0;
309
+ padding: 0;
310
+ }
311
+ .lite-kv-row {
312
+ display: flex;
313
+ align-items: center;
314
+ justify-content: space-between;
315
+ font-size: 13px;
316
+ line-height: 1.5;
317
+ padding: 8px 0;
318
+ }
319
+ .lite-kv-row + .lite-kv-row {
320
+ border-top: 1px solid #f1f4f8;
321
+ }
322
+ .lite-kv-label {
323
+ color: #425466;
324
+ }
325
+ .lite-kv-value {
326
+ color: #0a2540;
327
+ font-weight: 600;
328
+ }
329
+
330
+ /* ─── Resource Links / Cards ───────────────────────────────── */
331
+ .lite-resource-card {
332
+ display: block;
333
+ text-align: left;
334
+ padding: 12px 14px;
335
+ border: 1px solid #e6ebf1;
336
+ border-radius: 6px;
337
+ background: #fff;
338
+ color: #0a2540;
339
+ text-decoration: none;
340
+ transition: background 0.15s ease-out, border-color 0.15s ease-out, box-shadow 0.15s ease-out;
341
+ }
342
+ .lite-resource-card:hover {
343
+ background: #f8f7fd;
344
+ border-color: #cbd5e1;
345
+ text-decoration: none;
346
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
347
+ }
348
+ .lite-resource-card-title {
349
+ display: block;
350
+ font-size: 14px;
351
+ font-weight: 600;
352
+ margin-bottom: 2px;
353
+ color: #0a2540;
354
+ }
355
+ .lite-resource-card-desc {
356
+ display: block;
357
+ font-size: 12px;
358
+ color: #425466;
359
+ }
360
+
361
+ /* ─── Category Progress Grid (Parity Dashboard) ────────────── */
362
+ .lite-category-grid {
363
+ display: flex;
364
+ flex-wrap: wrap;
365
+ margin-left: -8px;
366
+ margin-right: -8px;
367
+ }
368
+ .lite-category-card {
369
+ flex: 1 1 260px;
370
+ margin: 8px;
371
+ padding: 12px 14px;
372
+ border: 1px solid #e6ebf1;
373
+ border-radius: 6px;
374
+ background: #fff;
375
+ }
376
+ .lite-category-card-header {
377
+ display: flex;
378
+ justify-content: space-between;
379
+ align-items: center;
380
+ margin-bottom: 8px;
381
+ }
382
+ .lite-category-card-header strong {
383
+ text-transform: capitalize;
384
+ color: #0a2540;
385
+ font-size: 13px;
386
+ }
387
+ .lite-category-card-footer {
388
+ font-size: 11px;
389
+ color: #425466;
390
+ display: flex;
391
+ justify-content: space-between;
392
+ }
254
393
 
255
394
  /* ─── Table ────────────────────────────────────────────────── */
256
395
  .lite-table {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/lite",
3
- "version": "0.22.2",
3
+ "version": "0.23.1",
4
4
  "description": "SSR-first lightweight admin UI for @svadmin with optional progressive enhancement",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "peerDependencies": {
58
58
  "svelte": "^5.57.1",
59
- "@svadmin/core": ">=0.34.2 <0.71.0",
59
+ "@svadmin/core": ">=0.34.2 <0.72.0",
60
60
  "@sveltejs/kit": "^3.0.0",
61
61
  "qrcode": "^1.5.4"
62
62
  },