@icen.ai/ui 0.2.1 → 0.4.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.
Files changed (121) hide show
  1. package/README.md +29 -16
  2. package/dist/base.css +389 -48
  3. package/dist/behaviors/accordion.mjs +20 -0
  4. package/dist/behaviors/carousel.mjs +30 -1
  5. package/dist/behaviors/charts.mjs +356 -0
  6. package/dist/behaviors/copy.mjs +4 -3
  7. package/dist/behaviors/datatable.mjs +968 -0
  8. package/dist/behaviors/input.mjs +20 -1
  9. package/dist/behaviors/modal.mjs +14 -0
  10. package/dist/behaviors/nav.mjs +31 -4
  11. package/dist/behaviors/sidebar.mjs +12 -0
  12. package/dist/behaviors/slider.mjs +35 -3
  13. package/dist/behaviors/tabs.mjs +100 -9
  14. package/dist/behaviors/tag-input.mjs +11 -0
  15. package/dist/behaviors/theme.mjs +26 -0
  16. package/dist/behaviors/toast.mjs +83 -15
  17. package/dist/behaviors/tree.mjs +57 -1
  18. package/dist/behaviors/upload.mjs +2 -3
  19. package/dist/cli.mjs +74 -0
  20. package/dist/components/accordion.mjs +3 -0
  21. package/dist/components/alert.mjs +2 -0
  22. package/dist/components/avatar.mjs +2 -0
  23. package/dist/components/breadcrumb.css +91 -18
  24. package/dist/components/breadcrumb.mjs +2 -0
  25. package/dist/components/btn.css +174 -14
  26. package/dist/components/btn.mjs +2 -0
  27. package/dist/components/card.css +118 -18
  28. package/dist/components/card.mjs +2 -0
  29. package/dist/components/carousel.mjs +3 -0
  30. package/dist/components/chart-area.css +15 -0
  31. package/dist/components/chart-area.mjs +4 -0
  32. package/dist/components/chart-bar.css +79 -0
  33. package/dist/components/chart-bar.mjs +4 -0
  34. package/dist/components/chart-gauge.css +38 -0
  35. package/dist/components/chart-gauge.mjs +4 -0
  36. package/dist/components/chart-heatmap.css +52 -0
  37. package/dist/components/chart-heatmap.mjs +4 -0
  38. package/dist/components/chart-line.css +15 -0
  39. package/dist/components/chart-line.mjs +4 -0
  40. package/dist/components/chart-pie.css +26 -0
  41. package/dist/components/chart-pie.mjs +4 -0
  42. package/dist/components/chart-radar.css +19 -0
  43. package/dist/components/chart-radar.mjs +4 -0
  44. package/dist/components/chart-sparkline.css +14 -0
  45. package/dist/components/chart-sparkline.mjs +4 -0
  46. package/dist/components/chart-stack.css +30 -0
  47. package/dist/components/chart-stack.mjs +4 -0
  48. package/dist/components/charts.css +66 -74
  49. package/dist/components/charts.mjs +12 -0
  50. package/dist/components/content.css +256 -74
  51. package/dist/components/context-menu.mjs +3 -0
  52. package/dist/components/datatable.css +429 -0
  53. package/dist/components/datatable.mjs +4 -0
  54. package/dist/components/desc.mjs +2 -0
  55. package/dist/components/dropdown.mjs +3 -0
  56. package/dist/components/empty.css +50 -10
  57. package/dist/components/empty.mjs +2 -0
  58. package/dist/components/feedback.css +158 -47
  59. package/dist/components/form.css +139 -22
  60. package/dist/components/input.css +165 -45
  61. package/dist/components/input.mjs +3 -0
  62. package/dist/components/kbd.mjs +2 -0
  63. package/dist/components/layout.mjs +2 -0
  64. package/dist/components/list.mjs +2 -0
  65. package/dist/components/media-card.mjs +2 -0
  66. package/dist/components/media.css +187 -40
  67. package/dist/components/menu.css +159 -32
  68. package/dist/components/modal.css +140 -34
  69. package/dist/components/modal.mjs +3 -0
  70. package/dist/components/nav.css +134 -32
  71. package/dist/components/nav.mjs +3 -0
  72. package/dist/components/pagination.css +105 -19
  73. package/dist/components/pagination.mjs +2 -0
  74. package/dist/components/panel.css +61 -6
  75. package/dist/components/panel.mjs +2 -0
  76. package/dist/components/pill.css +74 -14
  77. package/dist/components/pill.mjs +2 -0
  78. package/dist/components/popover.css +109 -7
  79. package/dist/components/popover.mjs +3 -0
  80. package/dist/components/progress.mjs +2 -0
  81. package/dist/components/rating.mjs +2 -0
  82. package/dist/components/result.mjs +2 -0
  83. package/dist/components/segmented.css +199 -50
  84. package/dist/components/segmented.mjs +2 -0
  85. package/dist/components/select.css +140 -39
  86. package/dist/components/select.mjs +3 -0
  87. package/dist/components/sidebar.css +162 -34
  88. package/dist/components/sidebar.mjs +3 -0
  89. package/dist/components/skeleton.mjs +2 -0
  90. package/dist/components/slider.css +169 -31
  91. package/dist/components/slider.mjs +3 -0
  92. package/dist/components/spinner.mjs +2 -0
  93. package/dist/components/stat.css +103 -8
  94. package/dist/components/stat.mjs +2 -0
  95. package/dist/components/steps.css +105 -31
  96. package/dist/components/steps.mjs +2 -0
  97. package/dist/components/switch.css +171 -54
  98. package/dist/components/switch.mjs +2 -0
  99. package/dist/components/table.css +114 -12
  100. package/dist/components/table.mjs +2 -0
  101. package/dist/components/tabs.css +104 -17
  102. package/dist/components/tabs.mjs +3 -0
  103. package/dist/components/tag-input.css +119 -23
  104. package/dist/components/tag-input.mjs +3 -0
  105. package/dist/components/timeline.mjs +2 -0
  106. package/dist/components/toast.css +85 -12
  107. package/dist/components/toast.mjs +3 -0
  108. package/dist/components/tooltip.css +86 -26
  109. package/dist/components/tooltip.mjs +2 -0
  110. package/dist/components/tree.mjs +3 -0
  111. package/dist/components/upload.css +144 -17
  112. package/dist/components/upload.mjs +3 -0
  113. package/dist/index.mjs +811 -42
  114. package/dist/registry.json +310 -2
  115. package/dist/retro-effects.css +264 -0
  116. package/dist/tokens/colors.css +18 -90
  117. package/dist/tokens/retro-effects.css +264 -0
  118. package/dist/tokens/style-profiles.css +47 -47
  119. package/dist/tokens.css +65 -137
  120. package/dist/ui.css +5069 -1026
  121. package/package.json +9 -1
@@ -28,7 +28,15 @@ function setup(carousel) {
28
28
  if (!track) return;
29
29
  track.style.transform = `translateX(${-index * 100}%)`;
30
30
  slides.forEach((s, i) => s.setAttribute("aria-hidden", String(i !== index)));
31
- dots.forEach((d, i) => d.classList.toggle("active", i === index));
31
+ dots.forEach((d, i) => {
32
+ d.classList.toggle("active", i === index);
33
+ if (i === index) d.setAttribute("aria-current", "true");
34
+ else d.removeAttribute("aria-current");
35
+ });
36
+ carousel.dispatchEvent(new CustomEvent("icen:carousel-change", {
37
+ bubbles: true,
38
+ detail: { index, count }
39
+ }));
32
40
  }
33
41
  function go(i) {
34
42
  index = (i % count + count) % count;
@@ -36,6 +44,27 @@ function setup(carousel) {
36
44
  }
37
45
  prev?.addEventListener("click", () => go(index - 1));
38
46
  next?.addEventListener("click", () => go(index + 1));
47
+ carousel.addEventListener("keydown", (ev) => {
48
+ const kev = ev;
49
+ switch (kev.key) {
50
+ case "ArrowLeft":
51
+ kev.preventDefault();
52
+ go(index - 1);
53
+ break;
54
+ case "ArrowRight":
55
+ kev.preventDefault();
56
+ go(index + 1);
57
+ break;
58
+ case "Home":
59
+ kev.preventDefault();
60
+ go(0);
61
+ break;
62
+ case "End":
63
+ kev.preventDefault();
64
+ go(count - 1);
65
+ break;
66
+ }
67
+ });
39
68
  render();
40
69
  }
41
70
  function initCarousel(root = document) {
@@ -258,10 +258,366 @@ function renderLine(el, opts) {
258
258
  wrap.append(svg, labelsRow(labels.slice(-7)));
259
259
  el.appendChild(wrap);
260
260
  }
261
+ function renderArea(el, opts) {
262
+ if (typeof document === "undefined") return;
263
+ el.textContent = "";
264
+ const n = Math.min(opts.labels.length, opts.values.length);
265
+ if (n === 0) {
266
+ renderEmpty(el, opts.emptyLabel);
267
+ return;
268
+ }
269
+ const labels = opts.labels.slice(0, n);
270
+ const values = opts.values.slice(0, n);
271
+ const width = 360;
272
+ const height = 150;
273
+ const pad = 14;
274
+ const max = Math.max(...values, 1);
275
+ const tone = toneVar(opts.tone);
276
+ const points = values.map((value, i) => ({
277
+ x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
278
+ y: height - pad - value / max * (height - pad * 2),
279
+ value,
280
+ label: labels[i] ?? ""
281
+ }));
282
+ const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
283
+ const last = points[points.length - 1];
284
+ const first = points[0];
285
+ const area = `${line} L${last.x.toFixed(1)},${height - pad} L${first.x.toFixed(1)},${height - pad} Z`;
286
+ const gradientId = `icen-chart-area-${++lineGradientSeq}`;
287
+ const wrap = document.createElement("div");
288
+ wrap.className = "chart-area";
289
+ const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img" });
290
+ const defs = svgEl("defs", {});
291
+ const gradient = svgEl("linearGradient", { id: gradientId, x1: "0", x2: "0", y1: "0", y2: "1" });
292
+ gradient.appendChild(svgEl("stop", { offset: "0%", "stop-color": tone, "stop-opacity": "0.5" }));
293
+ gradient.appendChild(svgEl("stop", { offset: "100%", "stop-color": tone, "stop-opacity": "0.05" }));
294
+ defs.appendChild(gradient);
295
+ svg.appendChild(defs);
296
+ for (let i = 0; i < 4; i++) {
297
+ const y = pad + i * (height - pad * 2) / 3;
298
+ svg.appendChild(svgEl("line", {
299
+ x1: String(pad),
300
+ x2: String(width - pad),
301
+ y1: String(y),
302
+ y2: String(y),
303
+ stroke: "var(--token-line-soft)",
304
+ "stroke-width": "1"
305
+ }));
306
+ }
307
+ svg.appendChild(svgEl("path", { d: area, fill: `url(#${gradientId})` }));
308
+ svg.appendChild(svgEl("path", {
309
+ d: line,
310
+ fill: "none",
311
+ stroke: tone,
312
+ "stroke-width": "1.5",
313
+ "stroke-linecap": "round",
314
+ "stroke-linejoin": "round"
315
+ }));
316
+ for (const p of points) {
317
+ const title = svgEl("title", {});
318
+ title.textContent = `${p.label}: ${fmt(opts, p.value)}`;
319
+ const inv = svgEl("circle", {
320
+ cx: p.x.toFixed(1),
321
+ cy: p.y.toFixed(1),
322
+ r: "2",
323
+ fill: "transparent"
324
+ });
325
+ inv.appendChild(title);
326
+ svg.appendChild(inv);
327
+ }
328
+ wrap.append(svg, labelsRow(labels.slice(-7)));
329
+ el.appendChild(wrap);
330
+ }
331
+ function renderRadar(el, opts) {
332
+ if (typeof document === "undefined") return;
333
+ el.textContent = "";
334
+ const axes = opts.axes;
335
+ const n = axes.length;
336
+ if (n < 3 || opts.series.length === 0) {
337
+ renderEmpty(el, opts.emptyLabel);
338
+ return;
339
+ }
340
+ let maxVal = opts.max ?? 0;
341
+ if (opts.max == null) {
342
+ for (const s of opts.series) {
343
+ for (let i = 0; i < n; i++) maxVal = Math.max(maxVal, s.values[i] ?? 0);
344
+ }
345
+ maxVal = niceCeil(maxVal);
346
+ }
347
+ if (maxVal <= 0) maxVal = 1;
348
+ const size = 200;
349
+ const cx = size / 2;
350
+ const cy = size / 2;
351
+ const radius = 78;
352
+ const levels = Math.max(2, opts.levels ?? 4);
353
+ const angleOf = (i) => -Math.PI / 2 + i * 2 * Math.PI / n;
354
+ const pointAt = (i, r) => ({
355
+ x: cx + r * Math.cos(angleOf(i)),
356
+ y: cy + r * Math.sin(angleOf(i))
357
+ });
358
+ const wrap = document.createElement("div");
359
+ wrap.className = "chart-radar";
360
+ const svg = svgEl("svg", { viewBox: `0 0 ${size} ${size}`, role: "img" });
361
+ for (let lv = 1; lv <= levels; lv++) {
362
+ const r = radius * lv / levels;
363
+ const pts = Array.from({ length: n }, (_, i) => {
364
+ const p = pointAt(i, r);
365
+ return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;
366
+ }).join(" ");
367
+ svg.appendChild(svgEl("polygon", {
368
+ points: pts,
369
+ fill: "none",
370
+ stroke: "var(--token-line-soft)",
371
+ "stroke-width": "1",
372
+ "stroke-dasharray": lv === levels ? "0" : "3 2"
373
+ }));
374
+ }
375
+ for (let i = 0; i < n; i++) {
376
+ const edge = pointAt(i, radius);
377
+ svg.appendChild(svgEl("line", {
378
+ x1: String(cx),
379
+ y1: String(cy),
380
+ x2: edge.x.toFixed(1),
381
+ y2: edge.y.toFixed(1),
382
+ stroke: "var(--token-line-soft)",
383
+ "stroke-width": "1"
384
+ }));
385
+ const labelP = pointAt(i, radius + 14);
386
+ const txt = svgEl("text", {
387
+ x: labelP.x.toFixed(1),
388
+ y: labelP.y.toFixed(1),
389
+ "text-anchor": "middle",
390
+ "dominant-baseline": "middle",
391
+ "font-size": "9",
392
+ fill: "var(--token-text-muted)"
393
+ });
394
+ txt.textContent = axes[i] ?? "";
395
+ svg.appendChild(txt);
396
+ }
397
+ const legend = document.createElement("div");
398
+ legend.className = "chart-legend";
399
+ for (const s of opts.series) {
400
+ const tone = toneVar(s.tone);
401
+ const pts = Array.from({ length: n }, (_, i) => {
402
+ const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
403
+ const p = pointAt(i, v / maxVal * radius);
404
+ return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;
405
+ }).join(" ");
406
+ const polyFill = svgEl("polygon", {
407
+ points: pts,
408
+ fill: tone,
409
+ "fill-opacity": "0.16",
410
+ stroke: tone,
411
+ "stroke-width": "2",
412
+ "stroke-linejoin": "round"
413
+ });
414
+ const title = svgEl("title", {});
415
+ title.textContent = `${s.name}: ${s.values.map((v) => fmt(opts, v)).join(" / ")}`;
416
+ polyFill.appendChild(title);
417
+ svg.appendChild(polyFill);
418
+ for (let i = 0; i < n; i++) {
419
+ const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
420
+ const p = pointAt(i, v / maxVal * radius);
421
+ svg.appendChild(svgEl("circle", {
422
+ cx: p.x.toFixed(1),
423
+ cy: p.y.toFixed(1),
424
+ r: "2.5",
425
+ fill: "var(--token-card)",
426
+ stroke: tone,
427
+ "stroke-width": "1.5"
428
+ }));
429
+ }
430
+ legend.appendChild(legendItem(s.name, "", s.tone));
431
+ }
432
+ wrap.append(svg, legend);
433
+ el.appendChild(wrap);
434
+ }
435
+ function niceCeil(v) {
436
+ if (v <= 0) return 1;
437
+ const exp = Math.floor(Math.log10(v));
438
+ const base = Math.pow(10, exp);
439
+ const frac = v / base;
440
+ let nice;
441
+ if (frac <= 1) nice = 1;
442
+ else if (frac <= 2) nice = 2;
443
+ else if (frac <= 5) nice = 5;
444
+ else nice = 10;
445
+ return nice * base;
446
+ }
447
+ function isoDate(d) {
448
+ const m = String(d.getMonth() + 1).padStart(2, "0");
449
+ const day = String(d.getDate()).padStart(2, "0");
450
+ return `${d.getFullYear()}-${m}-${day}`;
451
+ }
452
+ function renderHeatmap(el, opts) {
453
+ if (typeof document === "undefined") return;
454
+ el.textContent = "";
455
+ let entries;
456
+ if (opts.data && opts.data.length > 0) {
457
+ entries = opts.data;
458
+ } else if (opts.values && opts.values.length > 0) {
459
+ const today = /* @__PURE__ */ new Date();
460
+ entries = opts.values.map((value, i) => {
461
+ const d = new Date(today);
462
+ d.setDate(d.getDate() - (opts.values.length - 1 - i));
463
+ return { date: isoDate(d), value };
464
+ });
465
+ } else {
466
+ renderEmpty(el, opts.emptyLabel);
467
+ return;
468
+ }
469
+ const weeks = opts.weeks ?? Math.ceil(entries.length / 7);
470
+ if (entries.length > weeks * 7) entries = entries.slice(entries.length - weeks * 7);
471
+ const max = Math.max(...entries.map((e) => e.value), 1);
472
+ const levelOf = (v) => v <= 0 ? 0 : Math.min(4, Math.ceil(v / max * 4));
473
+ const wrap = document.createElement("div");
474
+ wrap.className = "chart-heatmap";
475
+ if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
476
+ const grid = document.createElement("div");
477
+ grid.className = "chart-heatmap-grid";
478
+ grid.setAttribute("role", "img");
479
+ const first = /* @__PURE__ */ new Date(`${entries[0].date}T00:00:00`);
480
+ const pad = (first.getDay() + 6) % 7;
481
+ for (let i = 0; i < pad; i++) {
482
+ const blank = document.createElement("span");
483
+ blank.className = "chart-heatmap-cell is-blank";
484
+ grid.appendChild(blank);
485
+ }
486
+ for (const entry of entries) {
487
+ const cell = document.createElement("span");
488
+ cell.className = "chart-heatmap-cell";
489
+ cell.dataset.level = String(levelOf(entry.value));
490
+ cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
491
+ grid.appendChild(cell);
492
+ }
493
+ const legend = document.createElement("div");
494
+ legend.className = "chart-heatmap-legend";
495
+ const less = document.createElement("span");
496
+ less.textContent = "\u5C11";
497
+ const more = document.createElement("span");
498
+ more.textContent = "\u591A";
499
+ legend.appendChild(less);
500
+ for (let lv = 0; lv <= 4; lv++) {
501
+ const cell = document.createElement("span");
502
+ cell.className = "chart-heatmap-cell";
503
+ cell.dataset.level = String(lv);
504
+ legend.appendChild(cell);
505
+ }
506
+ legend.appendChild(more);
507
+ wrap.append(grid, legend);
508
+ el.appendChild(wrap);
509
+ }
510
+ function renderSparkline(el, opts) {
511
+ if (typeof document === "undefined") return;
512
+ el.textContent = "";
513
+ const values = opts.values;
514
+ if (values.length === 0) {
515
+ renderEmpty(el, opts.emptyLabel);
516
+ return;
517
+ }
518
+ const width = 96;
519
+ const height = 28;
520
+ const pad = 3;
521
+ const max = Math.max(...values, 1);
522
+ const tone = toneVar(opts.tone);
523
+ const points = values.map((value, i) => ({
524
+ x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
525
+ y: height - pad - value / max * (height - pad * 2),
526
+ value
527
+ }));
528
+ const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
529
+ const last = points[points.length - 1];
530
+ const first = points[0];
531
+ const area = `${line} L${last.x.toFixed(1)},${height - pad} L${first.x.toFixed(1)},${height - pad} Z`;
532
+ const gradientId = `icen-chart-line-${++lineGradientSeq}`;
533
+ const wrap = document.createElement("div");
534
+ wrap.className = "chart-sparkline";
535
+ const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img" });
536
+ const defs = svgEl("defs", {});
537
+ const gradient = svgEl("linearGradient", { id: gradientId, x1: "0", x2: "0", y1: "0", y2: "1" });
538
+ gradient.appendChild(svgEl("stop", { offset: "0%", "stop-color": tone, "stop-opacity": "0.28" }));
539
+ gradient.appendChild(svgEl("stop", { offset: "100%", "stop-color": tone, "stop-opacity": "0.02" }));
540
+ defs.appendChild(gradient);
541
+ svg.appendChild(defs);
542
+ svg.appendChild(svgEl("path", { d: area, fill: `url(#${gradientId})` }));
543
+ svg.appendChild(svgEl("path", {
544
+ d: line,
545
+ fill: "none",
546
+ stroke: tone,
547
+ "stroke-width": "1.8",
548
+ "stroke-linecap": "round",
549
+ "stroke-linejoin": "round"
550
+ }));
551
+ const dot = svgEl("circle", {
552
+ cx: last.x.toFixed(1),
553
+ cy: last.y.toFixed(1),
554
+ r: "2.4",
555
+ fill: "var(--token-card)",
556
+ stroke: tone,
557
+ "stroke-width": "1.6"
558
+ });
559
+ const title = svgEl("title", {});
560
+ title.textContent = fmt(opts, last.value);
561
+ dot.appendChild(title);
562
+ svg.appendChild(dot);
563
+ wrap.appendChild(svg);
564
+ el.appendChild(wrap);
565
+ }
566
+ function renderGauge(el, opts) {
567
+ if (typeof document === "undefined") return;
568
+ el.textContent = "";
569
+ const max = opts.max ?? 100;
570
+ const ratio = max > 0 ? Math.min(1, Math.max(0, opts.value / max)) : 0;
571
+ const radius = 42;
572
+ const circumference = 2 * Math.PI * radius;
573
+ const wrap = document.createElement("div");
574
+ wrap.className = "chart-gauge";
575
+ if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
576
+ const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img" });
577
+ svg.style.transform = "rotate(-90deg)";
578
+ svg.appendChild(svgEl("circle", {
579
+ cx: "60",
580
+ cy: "60",
581
+ r: String(radius),
582
+ fill: "none",
583
+ stroke: "var(--token-line-soft)",
584
+ "stroke-width": "10"
585
+ }));
586
+ const dash = ratio * circumference;
587
+ svg.appendChild(svgEl("circle", {
588
+ cx: "60",
589
+ cy: "60",
590
+ r: String(radius),
591
+ fill: "none",
592
+ stroke: toneVar(opts.tone),
593
+ "stroke-width": "10",
594
+ "stroke-dasharray": `${dash} ${circumference - dash}`,
595
+ "stroke-linecap": "round"
596
+ }));
597
+ const center = document.createElement("div");
598
+ center.className = "chart-gauge-center";
599
+ const val = document.createElement("span");
600
+ val.className = "chart-gauge-value";
601
+ val.textContent = opts.formatValue ? opts.formatValue(opts.value) : `${Math.round(ratio * 100)}%`;
602
+ center.appendChild(val);
603
+ if (opts.label) {
604
+ const lab = document.createElement("span");
605
+ lab.className = "chart-gauge-label";
606
+ lab.textContent = opts.label;
607
+ center.appendChild(lab);
608
+ }
609
+ wrap.append(svg, center);
610
+ el.appendChild(wrap);
611
+ }
261
612
  export {
613
+ renderArea,
262
614
  renderDonut,
615
+ renderGauge,
263
616
  renderHBar,
617
+ renderHeatmap,
264
618
  renderLine,
619
+ renderRadar,
620
+ renderSparkline,
265
621
  renderStack,
266
622
  renderVBar
267
623
  };
@@ -31,11 +31,12 @@ async function copyText(text) {
31
31
  function flashDone(btn) {
32
32
  const prev = flashing.get(btn);
33
33
  if (prev) window.clearTimeout(prev.timer);
34
- const original = prev ? prev.original : btn.textContent;
35
- btn.textContent = "\u5DF2\u590D\u5236";
34
+ const iconOnly = btn.hasAttribute("data-copy-icon");
35
+ const original = prev ? prev.original : iconOnly ? null : btn.textContent;
36
+ if (!iconOnly) btn.textContent = "\u5DF2\u590D\u5236";
36
37
  btn.classList.add("done");
37
38
  const timer = window.setTimeout(() => {
38
- btn.textContent = original;
39
+ if (!iconOnly) btn.textContent = original;
39
40
  btn.classList.remove("done");
40
41
  flashing.delete(btn);
41
42
  }, 1400);