@icen.ai/ui 0.2.1 → 0.3.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 +29 -16
- package/dist/base.css +389 -48
- package/dist/behaviors/accordion.mjs +20 -0
- package/dist/behaviors/carousel.mjs +30 -1
- package/dist/behaviors/charts.mjs +168 -0
- package/dist/behaviors/copy.mjs +4 -3
- package/dist/behaviors/datatable.mjs +748 -0
- package/dist/behaviors/input.mjs +20 -1
- package/dist/behaviors/modal.mjs +14 -0
- package/dist/behaviors/nav.mjs +31 -4
- package/dist/behaviors/sidebar.mjs +12 -0
- package/dist/behaviors/slider.mjs +35 -3
- package/dist/behaviors/tabs.mjs +100 -9
- package/dist/behaviors/tag-input.mjs +11 -0
- package/dist/behaviors/theme.mjs +26 -0
- package/dist/behaviors/toast.mjs +83 -15
- package/dist/behaviors/tree.mjs +57 -1
- package/dist/behaviors/upload.mjs +2 -3
- package/dist/cli.mjs +74 -0
- package/dist/components/accordion.mjs +3 -0
- package/dist/components/alert.mjs +2 -0
- package/dist/components/avatar.mjs +2 -0
- package/dist/components/breadcrumb.css +91 -18
- package/dist/components/breadcrumb.mjs +2 -0
- package/dist/components/btn.css +174 -14
- package/dist/components/btn.mjs +2 -0
- package/dist/components/card.css +118 -18
- package/dist/components/card.mjs +2 -0
- package/dist/components/carousel.mjs +3 -0
- package/dist/components/charts.css +225 -33
- package/dist/components/charts.mjs +3 -0
- package/dist/components/content.css +256 -74
- package/dist/components/context-menu.mjs +3 -0
- package/dist/components/datatable.css +343 -0
- package/dist/components/datatable.mjs +4 -0
- package/dist/components/desc.mjs +2 -0
- package/dist/components/dropdown.mjs +3 -0
- package/dist/components/empty.css +50 -10
- package/dist/components/empty.mjs +2 -0
- package/dist/components/feedback.css +158 -47
- package/dist/components/form.css +139 -22
- package/dist/components/input.css +165 -45
- package/dist/components/input.mjs +3 -0
- package/dist/components/kbd.mjs +2 -0
- package/dist/components/layout.mjs +2 -0
- package/dist/components/list.mjs +2 -0
- package/dist/components/media-card.mjs +2 -0
- package/dist/components/media.css +187 -40
- package/dist/components/menu.css +159 -32
- package/dist/components/modal.css +140 -34
- package/dist/components/modal.mjs +3 -0
- package/dist/components/nav.css +134 -32
- package/dist/components/nav.mjs +3 -0
- package/dist/components/pagination.css +105 -19
- package/dist/components/pagination.mjs +2 -0
- package/dist/components/panel.css +61 -6
- package/dist/components/panel.mjs +2 -0
- package/dist/components/pill.css +74 -14
- package/dist/components/pill.mjs +2 -0
- package/dist/components/popover.css +109 -7
- package/dist/components/popover.mjs +3 -0
- package/dist/components/progress.mjs +2 -0
- package/dist/components/rating.mjs +2 -0
- package/dist/components/result.mjs +2 -0
- package/dist/components/segmented.css +199 -50
- package/dist/components/segmented.mjs +2 -0
- package/dist/components/select.css +140 -39
- package/dist/components/select.mjs +3 -0
- package/dist/components/sidebar.css +162 -34
- package/dist/components/sidebar.mjs +3 -0
- package/dist/components/skeleton.mjs +2 -0
- package/dist/components/slider.css +169 -31
- package/dist/components/slider.mjs +3 -0
- package/dist/components/spinner.mjs +2 -0
- package/dist/components/stat.css +103 -8
- package/dist/components/stat.mjs +2 -0
- package/dist/components/steps.css +105 -31
- package/dist/components/steps.mjs +2 -0
- package/dist/components/switch.css +171 -54
- package/dist/components/switch.mjs +2 -0
- package/dist/components/table.css +114 -12
- package/dist/components/table.mjs +2 -0
- package/dist/components/tabs.css +104 -17
- package/dist/components/tabs.mjs +3 -0
- package/dist/components/tag-input.css +119 -23
- package/dist/components/tag-input.mjs +3 -0
- package/dist/components/timeline.mjs +2 -0
- package/dist/components/toast.css +85 -12
- package/dist/components/toast.mjs +3 -0
- package/dist/components/tooltip.css +86 -26
- package/dist/components/tooltip.mjs +2 -0
- package/dist/components/tree.mjs +3 -0
- package/dist/components/upload.css +144 -17
- package/dist/components/upload.mjs +3 -0
- package/dist/index.mjs +623 -42
- package/dist/registry.json +197 -2
- package/dist/retro-effects.css +264 -0
- package/dist/tokens/colors.css +18 -90
- package/dist/tokens/retro-effects.css +264 -0
- package/dist/tokens/style-profiles.css +47 -47
- package/dist/tokens.css +65 -137
- package/dist/ui.css +4861 -1019
- 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) =>
|
|
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,178 @@ function renderLine(el, opts) {
|
|
|
258
258
|
wrap.append(svg, labelsRow(labels.slice(-7)));
|
|
259
259
|
el.appendChild(wrap);
|
|
260
260
|
}
|
|
261
|
+
function isoDate(d) {
|
|
262
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
263
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
264
|
+
return `${d.getFullYear()}-${m}-${day}`;
|
|
265
|
+
}
|
|
266
|
+
function renderHeatmap(el, opts) {
|
|
267
|
+
if (typeof document === "undefined") return;
|
|
268
|
+
el.textContent = "";
|
|
269
|
+
let entries;
|
|
270
|
+
if (opts.data && opts.data.length > 0) {
|
|
271
|
+
entries = opts.data;
|
|
272
|
+
} else if (opts.values && opts.values.length > 0) {
|
|
273
|
+
const today = /* @__PURE__ */ new Date();
|
|
274
|
+
entries = opts.values.map((value, i) => {
|
|
275
|
+
const d = new Date(today);
|
|
276
|
+
d.setDate(d.getDate() - (opts.values.length - 1 - i));
|
|
277
|
+
return { date: isoDate(d), value };
|
|
278
|
+
});
|
|
279
|
+
} else {
|
|
280
|
+
renderEmpty(el, opts.emptyLabel);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const weeks = opts.weeks ?? Math.ceil(entries.length / 7);
|
|
284
|
+
if (entries.length > weeks * 7) entries = entries.slice(entries.length - weeks * 7);
|
|
285
|
+
const max = Math.max(...entries.map((e) => e.value), 1);
|
|
286
|
+
const levelOf = (v) => v <= 0 ? 0 : Math.min(4, Math.ceil(v / max * 4));
|
|
287
|
+
const wrap = document.createElement("div");
|
|
288
|
+
wrap.className = "chart-heatmap";
|
|
289
|
+
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
290
|
+
const grid = document.createElement("div");
|
|
291
|
+
grid.className = "chart-heatmap-grid";
|
|
292
|
+
grid.setAttribute("role", "img");
|
|
293
|
+
const first = /* @__PURE__ */ new Date(`${entries[0].date}T00:00:00`);
|
|
294
|
+
const pad = (first.getDay() + 6) % 7;
|
|
295
|
+
for (let i = 0; i < pad; i++) {
|
|
296
|
+
const blank = document.createElement("span");
|
|
297
|
+
blank.className = "chart-heatmap-cell is-blank";
|
|
298
|
+
grid.appendChild(blank);
|
|
299
|
+
}
|
|
300
|
+
for (const entry of entries) {
|
|
301
|
+
const cell = document.createElement("span");
|
|
302
|
+
cell.className = "chart-heatmap-cell";
|
|
303
|
+
cell.dataset.level = String(levelOf(entry.value));
|
|
304
|
+
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
305
|
+
grid.appendChild(cell);
|
|
306
|
+
}
|
|
307
|
+
const legend = document.createElement("div");
|
|
308
|
+
legend.className = "chart-heatmap-legend";
|
|
309
|
+
const less = document.createElement("span");
|
|
310
|
+
less.textContent = "\u5C11";
|
|
311
|
+
const more = document.createElement("span");
|
|
312
|
+
more.textContent = "\u591A";
|
|
313
|
+
legend.appendChild(less);
|
|
314
|
+
for (let lv = 0; lv <= 4; lv++) {
|
|
315
|
+
const cell = document.createElement("span");
|
|
316
|
+
cell.className = "chart-heatmap-cell";
|
|
317
|
+
cell.dataset.level = String(lv);
|
|
318
|
+
legend.appendChild(cell);
|
|
319
|
+
}
|
|
320
|
+
legend.appendChild(more);
|
|
321
|
+
wrap.append(grid, legend);
|
|
322
|
+
el.appendChild(wrap);
|
|
323
|
+
}
|
|
324
|
+
function renderSparkline(el, opts) {
|
|
325
|
+
if (typeof document === "undefined") return;
|
|
326
|
+
el.textContent = "";
|
|
327
|
+
const values = opts.values;
|
|
328
|
+
if (values.length === 0) {
|
|
329
|
+
renderEmpty(el, opts.emptyLabel);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const width = 96;
|
|
333
|
+
const height = 28;
|
|
334
|
+
const pad = 3;
|
|
335
|
+
const max = Math.max(...values, 1);
|
|
336
|
+
const tone = toneVar(opts.tone);
|
|
337
|
+
const points = values.map((value, i) => ({
|
|
338
|
+
x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
|
|
339
|
+
y: height - pad - value / max * (height - pad * 2),
|
|
340
|
+
value
|
|
341
|
+
}));
|
|
342
|
+
const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
|
|
343
|
+
const last = points[points.length - 1];
|
|
344
|
+
const first = points[0];
|
|
345
|
+
const area = `${line} L${last.x.toFixed(1)},${height - pad} L${first.x.toFixed(1)},${height - pad} Z`;
|
|
346
|
+
const gradientId = `icen-chart-line-${++lineGradientSeq}`;
|
|
347
|
+
const wrap = document.createElement("div");
|
|
348
|
+
wrap.className = "chart-sparkline";
|
|
349
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img" });
|
|
350
|
+
const defs = svgEl("defs", {});
|
|
351
|
+
const gradient = svgEl("linearGradient", { id: gradientId, x1: "0", x2: "0", y1: "0", y2: "1" });
|
|
352
|
+
gradient.appendChild(svgEl("stop", { offset: "0%", "stop-color": tone, "stop-opacity": "0.28" }));
|
|
353
|
+
gradient.appendChild(svgEl("stop", { offset: "100%", "stop-color": tone, "stop-opacity": "0.02" }));
|
|
354
|
+
defs.appendChild(gradient);
|
|
355
|
+
svg.appendChild(defs);
|
|
356
|
+
svg.appendChild(svgEl("path", { d: area, fill: `url(#${gradientId})` }));
|
|
357
|
+
svg.appendChild(svgEl("path", {
|
|
358
|
+
d: line,
|
|
359
|
+
fill: "none",
|
|
360
|
+
stroke: tone,
|
|
361
|
+
"stroke-width": "1.8",
|
|
362
|
+
"stroke-linecap": "round",
|
|
363
|
+
"stroke-linejoin": "round"
|
|
364
|
+
}));
|
|
365
|
+
const dot = svgEl("circle", {
|
|
366
|
+
cx: last.x.toFixed(1),
|
|
367
|
+
cy: last.y.toFixed(1),
|
|
368
|
+
r: "2.4",
|
|
369
|
+
fill: "var(--token-card)",
|
|
370
|
+
stroke: tone,
|
|
371
|
+
"stroke-width": "1.6"
|
|
372
|
+
});
|
|
373
|
+
const title = svgEl("title", {});
|
|
374
|
+
title.textContent = fmt(opts, last.value);
|
|
375
|
+
dot.appendChild(title);
|
|
376
|
+
svg.appendChild(dot);
|
|
377
|
+
wrap.appendChild(svg);
|
|
378
|
+
el.appendChild(wrap);
|
|
379
|
+
}
|
|
380
|
+
function renderGauge(el, opts) {
|
|
381
|
+
if (typeof document === "undefined") return;
|
|
382
|
+
el.textContent = "";
|
|
383
|
+
const max = opts.max ?? 100;
|
|
384
|
+
const ratio = max > 0 ? Math.min(1, Math.max(0, opts.value / max)) : 0;
|
|
385
|
+
const radius = 42;
|
|
386
|
+
const circumference = 2 * Math.PI * radius;
|
|
387
|
+
const wrap = document.createElement("div");
|
|
388
|
+
wrap.className = "chart-gauge";
|
|
389
|
+
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
390
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img" });
|
|
391
|
+
svg.style.transform = "rotate(-90deg)";
|
|
392
|
+
svg.appendChild(svgEl("circle", {
|
|
393
|
+
cx: "60",
|
|
394
|
+
cy: "60",
|
|
395
|
+
r: String(radius),
|
|
396
|
+
fill: "none",
|
|
397
|
+
stroke: "var(--token-line-soft)",
|
|
398
|
+
"stroke-width": "10"
|
|
399
|
+
}));
|
|
400
|
+
const dash = ratio * circumference;
|
|
401
|
+
svg.appendChild(svgEl("circle", {
|
|
402
|
+
cx: "60",
|
|
403
|
+
cy: "60",
|
|
404
|
+
r: String(radius),
|
|
405
|
+
fill: "none",
|
|
406
|
+
stroke: toneVar(opts.tone),
|
|
407
|
+
"stroke-width": "10",
|
|
408
|
+
"stroke-dasharray": `${dash} ${circumference - dash}`,
|
|
409
|
+
"stroke-linecap": "round"
|
|
410
|
+
}));
|
|
411
|
+
const center = document.createElement("div");
|
|
412
|
+
center.className = "chart-gauge-center";
|
|
413
|
+
const val = document.createElement("span");
|
|
414
|
+
val.className = "chart-gauge-value";
|
|
415
|
+
val.textContent = opts.formatValue ? opts.formatValue(opts.value) : `${Math.round(ratio * 100)}%`;
|
|
416
|
+
center.appendChild(val);
|
|
417
|
+
if (opts.label) {
|
|
418
|
+
const lab = document.createElement("span");
|
|
419
|
+
lab.className = "chart-gauge-label";
|
|
420
|
+
lab.textContent = opts.label;
|
|
421
|
+
center.appendChild(lab);
|
|
422
|
+
}
|
|
423
|
+
wrap.append(svg, center);
|
|
424
|
+
el.appendChild(wrap);
|
|
425
|
+
}
|
|
261
426
|
export {
|
|
262
427
|
renderDonut,
|
|
428
|
+
renderGauge,
|
|
263
429
|
renderHBar,
|
|
430
|
+
renderHeatmap,
|
|
264
431
|
renderLine,
|
|
432
|
+
renderSparkline,
|
|
265
433
|
renderStack,
|
|
266
434
|
renderVBar
|
|
267
435
|
};
|
package/dist/behaviors/copy.mjs
CHANGED
|
@@ -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
|
|
35
|
-
btn.textContent
|
|
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);
|