@vespera-ui/vue 0.4.0 → 0.6.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/dist/index.cjs +469 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +283 -1
- package/dist/index.d.ts +283 -1
- package/dist/index.js +461 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -22,25 +22,31 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
Accordion: () => Accordion,
|
|
24
24
|
Alert: () => Alert,
|
|
25
|
+
AreaChart: () => AreaChart,
|
|
25
26
|
Avatar: () => Avatar,
|
|
26
27
|
AvatarGroup: () => AvatarGroup,
|
|
27
28
|
Badge: () => Badge,
|
|
28
29
|
Banner: () => Banner,
|
|
30
|
+
BarChart: () => BarChart,
|
|
29
31
|
Breadcrumb: () => Breadcrumb,
|
|
30
32
|
Button: () => Button,
|
|
31
33
|
Card: () => Card,
|
|
32
34
|
CardHead: () => CardHead,
|
|
33
35
|
Checkbox: () => Checkbox,
|
|
34
36
|
CircularProgress: () => CircularProgress,
|
|
37
|
+
CopyButton: () => CopyButton,
|
|
35
38
|
DescriptionList: () => DescriptionList,
|
|
36
39
|
Divider: () => Divider,
|
|
37
40
|
Donut: () => Donut,
|
|
38
41
|
EmptyState: () => EmptyState,
|
|
39
42
|
Field: () => Field,
|
|
40
43
|
IconButton: () => IconButton,
|
|
44
|
+
InlineEdit: () => InlineEdit,
|
|
41
45
|
Input: () => Input,
|
|
42
46
|
Kbd: () => Kbd,
|
|
43
47
|
NativeSelect: () => NativeSelect,
|
|
48
|
+
NumberStepper: () => NumberStepper,
|
|
49
|
+
OTPInput: () => OTPInput,
|
|
44
50
|
Pagination: () => Pagination,
|
|
45
51
|
Progress: () => Progress,
|
|
46
52
|
Radio: () => Radio,
|
|
@@ -58,6 +64,8 @@ __export(index_exports, {
|
|
|
58
64
|
Tag: () => Tag,
|
|
59
65
|
Textarea: () => Textarea,
|
|
60
66
|
Timeline: () => Timeline,
|
|
67
|
+
Tree: () => Tree,
|
|
68
|
+
niceNum: () => niceNum,
|
|
61
69
|
smoothPath: () => smoothPath
|
|
62
70
|
});
|
|
63
71
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1270,29 +1278,488 @@ var StatCard = (0, import_vue.defineComponent)({
|
|
|
1270
1278
|
);
|
|
1271
1279
|
}
|
|
1272
1280
|
});
|
|
1281
|
+
var ICON_CHECK = "M20 6L9 17l-5-5";
|
|
1282
|
+
var ICON_DOC = "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8zM14 2v6h6";
|
|
1283
|
+
var ICON_PENCIL = "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4z";
|
|
1284
|
+
var NumberStepper = (0, import_vue.defineComponent)({
|
|
1285
|
+
name: "VspNumberStepper",
|
|
1286
|
+
props: {
|
|
1287
|
+
modelValue: { type: Number, default: 0 },
|
|
1288
|
+
min: { type: Number, default: void 0 },
|
|
1289
|
+
max: { type: Number, default: void 0 },
|
|
1290
|
+
step: { type: Number, default: 1 },
|
|
1291
|
+
unit: { type: String, default: void 0 }
|
|
1292
|
+
},
|
|
1293
|
+
emits: ["update:modelValue"],
|
|
1294
|
+
setup(props, { emit }) {
|
|
1295
|
+
const set = (v) => {
|
|
1296
|
+
let n = v;
|
|
1297
|
+
if (props.min != null && n < props.min) n = props.min;
|
|
1298
|
+
if (props.max != null && n > props.max) n = props.max;
|
|
1299
|
+
emit("update:modelValue", n);
|
|
1300
|
+
};
|
|
1301
|
+
return () => (0, import_vue.h)("div", { class: "ui-stepper" }, [
|
|
1302
|
+
(0, import_vue.h)(
|
|
1303
|
+
"button",
|
|
1304
|
+
{
|
|
1305
|
+
type: "button",
|
|
1306
|
+
"aria-label": "Decrease",
|
|
1307
|
+
disabled: props.min != null && props.modelValue <= props.min,
|
|
1308
|
+
onClick: () => set(props.modelValue - props.step)
|
|
1309
|
+
},
|
|
1310
|
+
"\u2212"
|
|
1311
|
+
),
|
|
1312
|
+
(0, import_vue.h)("span", { class: "val" }, [
|
|
1313
|
+
props.modelValue,
|
|
1314
|
+
props.unit ? (0, import_vue.h)("i", null, props.unit) : null
|
|
1315
|
+
]),
|
|
1316
|
+
(0, import_vue.h)(
|
|
1317
|
+
"button",
|
|
1318
|
+
{
|
|
1319
|
+
type: "button",
|
|
1320
|
+
"aria-label": "Increase",
|
|
1321
|
+
disabled: props.max != null && props.modelValue >= props.max,
|
|
1322
|
+
onClick: () => set(props.modelValue + props.step)
|
|
1323
|
+
},
|
|
1324
|
+
"+"
|
|
1325
|
+
)
|
|
1326
|
+
]);
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
var CopyButton = (0, import_vue.defineComponent)({
|
|
1330
|
+
name: "VspCopyButton",
|
|
1331
|
+
props: {
|
|
1332
|
+
text: { type: String, required: true },
|
|
1333
|
+
label: { type: String, default: "Copy" },
|
|
1334
|
+
size: { type: String, default: "sm" }
|
|
1335
|
+
},
|
|
1336
|
+
setup(props) {
|
|
1337
|
+
const done = (0, import_vue.ref)(false);
|
|
1338
|
+
const copy = async () => {
|
|
1339
|
+
try {
|
|
1340
|
+
await navigator.clipboard?.writeText(props.text);
|
|
1341
|
+
} catch {
|
|
1342
|
+
}
|
|
1343
|
+
done.value = true;
|
|
1344
|
+
setTimeout(() => done.value = false, 1400);
|
|
1345
|
+
};
|
|
1346
|
+
return () => (0, import_vue.h)(
|
|
1347
|
+
"button",
|
|
1348
|
+
{
|
|
1349
|
+
type: "button",
|
|
1350
|
+
class: cx("btn", "btn-ghost", props.size === "sm" && "btn-sm"),
|
|
1351
|
+
onClick: copy
|
|
1352
|
+
},
|
|
1353
|
+
[
|
|
1354
|
+
done.value ? (0, import_vue.h)("span", { style: { color: "var(--success)", display: "inline-flex" } }, [
|
|
1355
|
+
svgIcon(ICON_CHECK, 15)
|
|
1356
|
+
]) : svgIcon(ICON_DOC, 15),
|
|
1357
|
+
done.value ? "Copied" : props.label
|
|
1358
|
+
]
|
|
1359
|
+
);
|
|
1360
|
+
}
|
|
1361
|
+
});
|
|
1362
|
+
var InlineEdit = (0, import_vue.defineComponent)({
|
|
1363
|
+
name: "VspInlineEdit",
|
|
1364
|
+
props: {
|
|
1365
|
+
value: { type: String, default: "" },
|
|
1366
|
+
placeholder: { type: String, default: "Empty" }
|
|
1367
|
+
},
|
|
1368
|
+
emits: ["save"],
|
|
1369
|
+
setup(props, { emit }) {
|
|
1370
|
+
const editing = (0, import_vue.ref)(false);
|
|
1371
|
+
const draft = (0, import_vue.ref)(props.value);
|
|
1372
|
+
const commit = () => {
|
|
1373
|
+
editing.value = false;
|
|
1374
|
+
if (draft.value !== props.value) emit("save", draft.value);
|
|
1375
|
+
};
|
|
1376
|
+
return () => editing.value ? (0, import_vue.h)("input", {
|
|
1377
|
+
class: "ui-input",
|
|
1378
|
+
value: draft.value,
|
|
1379
|
+
style: { height: "32px", maxWidth: "240px" },
|
|
1380
|
+
onVnodeMounted: (vn) => vn.el?.focus(),
|
|
1381
|
+
onInput: (e) => draft.value = e.target.value,
|
|
1382
|
+
onBlur: commit,
|
|
1383
|
+
onKeydown: (e) => {
|
|
1384
|
+
if (e.key === "Enter") commit();
|
|
1385
|
+
if (e.key === "Escape") {
|
|
1386
|
+
draft.value = props.value;
|
|
1387
|
+
editing.value = false;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
}) : (0, import_vue.h)(
|
|
1391
|
+
"span",
|
|
1392
|
+
{
|
|
1393
|
+
class: "ui-inline",
|
|
1394
|
+
onClick: () => {
|
|
1395
|
+
draft.value = props.value;
|
|
1396
|
+
editing.value = true;
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
[
|
|
1400
|
+
(0, import_vue.h)(
|
|
1401
|
+
"span",
|
|
1402
|
+
{ style: { color: props.value ? "var(--text)" : "var(--text-faint)" } },
|
|
1403
|
+
props.value || props.placeholder
|
|
1404
|
+
),
|
|
1405
|
+
(0, import_vue.h)("span", { class: "pen", style: { display: "inline-flex" } }, [
|
|
1406
|
+
svgIcon(ICON_PENCIL, 14)
|
|
1407
|
+
])
|
|
1408
|
+
]
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
var svgIconClass = (d, size, cls) => (0, import_vue.h)(
|
|
1413
|
+
"svg",
|
|
1414
|
+
{
|
|
1415
|
+
class: cls,
|
|
1416
|
+
viewBox: "0 0 24 24",
|
|
1417
|
+
width: size,
|
|
1418
|
+
height: size,
|
|
1419
|
+
fill: "none",
|
|
1420
|
+
stroke: "currentColor",
|
|
1421
|
+
"stroke-width": 2,
|
|
1422
|
+
"stroke-linecap": "round",
|
|
1423
|
+
"stroke-linejoin": "round"
|
|
1424
|
+
},
|
|
1425
|
+
[(0, import_vue.h)("path", { d })]
|
|
1426
|
+
);
|
|
1427
|
+
var ICON_LAYERS = "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5";
|
|
1428
|
+
var treeNodeId = (n) => n.id ?? n.label;
|
|
1429
|
+
var VspTreeNode = (0, import_vue.defineComponent)({
|
|
1430
|
+
name: "VspTreeNode",
|
|
1431
|
+
props: {
|
|
1432
|
+
node: { type: Object, required: true },
|
|
1433
|
+
expanded: { type: Object, required: true },
|
|
1434
|
+
selected: { type: String, default: null },
|
|
1435
|
+
toggle: { type: Function, required: true },
|
|
1436
|
+
select: { type: Function, required: true }
|
|
1437
|
+
},
|
|
1438
|
+
setup(props) {
|
|
1439
|
+
return () => {
|
|
1440
|
+
const node = props.node;
|
|
1441
|
+
const id = treeNodeId(node);
|
|
1442
|
+
const kids = node.children ?? [];
|
|
1443
|
+
const hasKids = kids.length > 0;
|
|
1444
|
+
const open = props.expanded.has(id);
|
|
1445
|
+
return (0, import_vue.h)("div", null, [
|
|
1446
|
+
(0, import_vue.h)(
|
|
1447
|
+
"div",
|
|
1448
|
+
{
|
|
1449
|
+
class: cx("ui-tree-row", open && "open", props.selected === id && "sel"),
|
|
1450
|
+
onClick: () => {
|
|
1451
|
+
if (hasKids) props.toggle(id);
|
|
1452
|
+
props.select(id);
|
|
1453
|
+
}
|
|
1454
|
+
},
|
|
1455
|
+
[
|
|
1456
|
+
hasKids ? svgIconClass(ICON_PATHS.chevR, 16, "tw-chev") : (0, import_vue.h)("span", { style: { width: "16px", flexShrink: 0 } }),
|
|
1457
|
+
svgIconClass(hasKids ? ICON_LAYERS : ICON_DOC, 16, "tw-icon"),
|
|
1458
|
+
(0, import_vue.h)(
|
|
1459
|
+
"span",
|
|
1460
|
+
{
|
|
1461
|
+
style: {
|
|
1462
|
+
flex: 1,
|
|
1463
|
+
minWidth: 0,
|
|
1464
|
+
overflow: "hidden",
|
|
1465
|
+
textOverflow: "ellipsis",
|
|
1466
|
+
whiteSpace: "nowrap"
|
|
1467
|
+
}
|
|
1468
|
+
},
|
|
1469
|
+
node.label
|
|
1470
|
+
),
|
|
1471
|
+
node.badge != null ? (0, import_vue.h)(
|
|
1472
|
+
"span",
|
|
1473
|
+
{ class: "mono", style: { fontSize: "11px", color: "var(--text-faint)" } },
|
|
1474
|
+
node.badge
|
|
1475
|
+
) : null
|
|
1476
|
+
]
|
|
1477
|
+
),
|
|
1478
|
+
hasKids && open ? (0, import_vue.h)(
|
|
1479
|
+
"div",
|
|
1480
|
+
{ class: "ui-tree-children" },
|
|
1481
|
+
kids.map(
|
|
1482
|
+
(c, i) => (0, import_vue.h)(VspTreeNode, {
|
|
1483
|
+
key: i,
|
|
1484
|
+
node: c,
|
|
1485
|
+
expanded: props.expanded,
|
|
1486
|
+
selected: props.selected,
|
|
1487
|
+
toggle: props.toggle,
|
|
1488
|
+
select: props.select
|
|
1489
|
+
})
|
|
1490
|
+
)
|
|
1491
|
+
) : null
|
|
1492
|
+
]);
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
});
|
|
1496
|
+
var Tree = (0, import_vue.defineComponent)({
|
|
1497
|
+
name: "VspTree",
|
|
1498
|
+
props: {
|
|
1499
|
+
data: { type: Array, default: () => [] },
|
|
1500
|
+
defaultExpanded: { type: Array, default: () => [] }
|
|
1501
|
+
},
|
|
1502
|
+
setup(props) {
|
|
1503
|
+
const expanded = (0, import_vue.ref)(new Set(props.defaultExpanded));
|
|
1504
|
+
const selected = (0, import_vue.ref)(null);
|
|
1505
|
+
const toggle = (id) => {
|
|
1506
|
+
const n = new Set(expanded.value);
|
|
1507
|
+
if (n.has(id)) n.delete(id);
|
|
1508
|
+
else n.add(id);
|
|
1509
|
+
expanded.value = n;
|
|
1510
|
+
};
|
|
1511
|
+
return () => (0, import_vue.h)(
|
|
1512
|
+
"div",
|
|
1513
|
+
{ class: "ui-tree" },
|
|
1514
|
+
props.data.map(
|
|
1515
|
+
(n, i) => (0, import_vue.h)(VspTreeNode, {
|
|
1516
|
+
key: i,
|
|
1517
|
+
node: n,
|
|
1518
|
+
expanded: expanded.value,
|
|
1519
|
+
selected: selected.value,
|
|
1520
|
+
toggle,
|
|
1521
|
+
select: (id) => selected.value = id
|
|
1522
|
+
})
|
|
1523
|
+
)
|
|
1524
|
+
);
|
|
1525
|
+
}
|
|
1526
|
+
});
|
|
1527
|
+
var OTPInput = (0, import_vue.defineComponent)({
|
|
1528
|
+
name: "VspOTPInput",
|
|
1529
|
+
props: {
|
|
1530
|
+
length: { type: Number, default: 6 },
|
|
1531
|
+
modelValue: { type: String, default: "" }
|
|
1532
|
+
},
|
|
1533
|
+
emits: ["update:modelValue"],
|
|
1534
|
+
setup(props, { emit }) {
|
|
1535
|
+
const refs = [];
|
|
1536
|
+
const set = (i, ch) => {
|
|
1537
|
+
const chars = Array.from({ length: props.length }, (_, k) => props.modelValue[k] ?? "");
|
|
1538
|
+
chars[i] = ch.slice(-1);
|
|
1539
|
+
emit("update:modelValue", chars.join(""));
|
|
1540
|
+
if (ch && i < props.length - 1) refs[i + 1]?.focus();
|
|
1541
|
+
};
|
|
1542
|
+
const onKey = (i, e) => {
|
|
1543
|
+
if (e.key === "Backspace" && !props.modelValue[i] && i > 0) refs[i - 1]?.focus();
|
|
1544
|
+
};
|
|
1545
|
+
return () => (0, import_vue.h)(
|
|
1546
|
+
"div",
|
|
1547
|
+
{ class: "ui-otp" },
|
|
1548
|
+
Array.from(
|
|
1549
|
+
{ length: props.length },
|
|
1550
|
+
(_, i) => (0, import_vue.h)("input", {
|
|
1551
|
+
key: i,
|
|
1552
|
+
ref: (el) => {
|
|
1553
|
+
refs[i] = el;
|
|
1554
|
+
},
|
|
1555
|
+
inputmode: "numeric",
|
|
1556
|
+
maxlength: 1,
|
|
1557
|
+
value: props.modelValue[i] ?? "",
|
|
1558
|
+
onInput: (e) => set(i, e.target.value.replace(/\D/g, "")),
|
|
1559
|
+
onKeydown: (e) => onKey(i, e)
|
|
1560
|
+
})
|
|
1561
|
+
)
|
|
1562
|
+
);
|
|
1563
|
+
}
|
|
1564
|
+
});
|
|
1565
|
+
function niceNum(n) {
|
|
1566
|
+
if (Math.abs(n) >= 1e6) return (n / 1e6).toFixed(n % 1e6 === 0 ? 0 : 1) + "M";
|
|
1567
|
+
if (Math.abs(n) >= 1e3) return (n / 1e3).toFixed(n % 1e3 === 0 ? 0 : 1) + "k";
|
|
1568
|
+
return String(n);
|
|
1569
|
+
}
|
|
1570
|
+
var AreaChart = (0, import_vue.defineComponent)({
|
|
1571
|
+
name: "VspAreaChart",
|
|
1572
|
+
props: {
|
|
1573
|
+
series: { type: Array, default: () => [] },
|
|
1574
|
+
labels: { type: Array, default: void 0 },
|
|
1575
|
+
width: { type: Number, default: 760 },
|
|
1576
|
+
height: { type: Number, default: 260 },
|
|
1577
|
+
color: { type: String, default: "var(--accent)" },
|
|
1578
|
+
color2: { type: String, default: "var(--accent-2)" },
|
|
1579
|
+
dual: Boolean
|
|
1580
|
+
},
|
|
1581
|
+
setup(props) {
|
|
1582
|
+
const gid = "ac" + (0, import_vue.useId)().replace(/[^a-zA-Z0-9]/g, "");
|
|
1583
|
+
const txt = (x, y, anchor, val) => (0, import_vue.h)(
|
|
1584
|
+
"text",
|
|
1585
|
+
{
|
|
1586
|
+
x,
|
|
1587
|
+
y,
|
|
1588
|
+
"text-anchor": anchor,
|
|
1589
|
+
"font-size": "10",
|
|
1590
|
+
fill: "var(--text-faint)",
|
|
1591
|
+
"font-family": "var(--font-mono)"
|
|
1592
|
+
},
|
|
1593
|
+
val
|
|
1594
|
+
);
|
|
1595
|
+
return () => {
|
|
1596
|
+
const w = props.width;
|
|
1597
|
+
const height = props.height;
|
|
1598
|
+
const padL = 38;
|
|
1599
|
+
const padB = 26;
|
|
1600
|
+
const padT = 12;
|
|
1601
|
+
const padR = 8;
|
|
1602
|
+
const innerW = Math.max(10, w - padL - padR);
|
|
1603
|
+
const innerH = height - padB - padT;
|
|
1604
|
+
const s0 = props.series[0] ?? [];
|
|
1605
|
+
const s1 = props.series[1];
|
|
1606
|
+
const all = props.dual && s1 ? [...s0, ...s1] : s0;
|
|
1607
|
+
const max = Math.max(...all, 0) * 1.12;
|
|
1608
|
+
const rng = max || 1;
|
|
1609
|
+
const sx = (i, len) => padL + i / Math.max(1, len - 1) * innerW;
|
|
1610
|
+
const sy = (v) => padT + innerH - v / rng * innerH;
|
|
1611
|
+
const mkPts = (arr) => arr.map((v, i) => [sx(i, arr.length), sy(v)]);
|
|
1612
|
+
const lines = (props.dual && s1 ? [s0, s1] : [s0]).map(mkPts);
|
|
1613
|
+
const yTicks = 4;
|
|
1614
|
+
const grid = Array.from({ length: yTicks + 1 }, (_, i) => {
|
|
1615
|
+
const y = sy(max / yTicks * i);
|
|
1616
|
+
return (0, import_vue.h)("g", { key: "g" + i }, [
|
|
1617
|
+
(0, import_vue.h)("line", {
|
|
1618
|
+
x1: padL,
|
|
1619
|
+
x2: w - padR,
|
|
1620
|
+
y1: y,
|
|
1621
|
+
y2: y,
|
|
1622
|
+
stroke: "var(--grid-line)",
|
|
1623
|
+
"stroke-width": "1"
|
|
1624
|
+
}),
|
|
1625
|
+
txt(padL - 8, y + 3.5, "end", niceNum(Math.round(max / yTicks * i)))
|
|
1626
|
+
]);
|
|
1627
|
+
});
|
|
1628
|
+
const lbls = props.labels ? props.labels.map(
|
|
1629
|
+
(lb, i) => i % Math.ceil(props.labels.length / 7) === 0 ? txt(sx(i, props.labels.length), height - 8, "middle", lb) : null
|
|
1630
|
+
) : [];
|
|
1631
|
+
const lineEls = lines.map((pts, li) => {
|
|
1632
|
+
const stroke = li === 0 ? props.color : props.color2;
|
|
1633
|
+
const lastPt = pts[pts.length - 1];
|
|
1634
|
+
const firstPt = pts[0];
|
|
1635
|
+
return (0, import_vue.h)("g", { key: "ln" + li }, [
|
|
1636
|
+
li === 0 && firstPt && lastPt ? (0, import_vue.h)("path", {
|
|
1637
|
+
d: `${smoothPath(pts)} L ${lastPt[0]} ${padT + innerH} L ${firstPt[0]} ${padT + innerH} Z`,
|
|
1638
|
+
fill: `url(#${gid})`
|
|
1639
|
+
}) : null,
|
|
1640
|
+
(0, import_vue.h)("path", {
|
|
1641
|
+
d: smoothPath(pts),
|
|
1642
|
+
fill: "none",
|
|
1643
|
+
stroke,
|
|
1644
|
+
"stroke-width": "2.4",
|
|
1645
|
+
"stroke-linecap": "round",
|
|
1646
|
+
"stroke-dasharray": li === 1 ? "5 5" : void 0,
|
|
1647
|
+
style: { opacity: li === 1 ? 0.7 : 1 }
|
|
1648
|
+
})
|
|
1649
|
+
]);
|
|
1650
|
+
});
|
|
1651
|
+
return (0, import_vue.h)("svg", { width: w, height, style: { display: "block" } }, [
|
|
1652
|
+
(0, import_vue.h)("defs", null, [
|
|
1653
|
+
(0, import_vue.h)("linearGradient", { id: gid, x1: "0", x2: "0", y1: "0", y2: "1" }, [
|
|
1654
|
+
(0, import_vue.h)("stop", { offset: "0", "stop-color": props.color, "stop-opacity": "0.22" }),
|
|
1655
|
+
(0, import_vue.h)("stop", { offset: "1", "stop-color": props.color, "stop-opacity": "0" })
|
|
1656
|
+
])
|
|
1657
|
+
]),
|
|
1658
|
+
...grid,
|
|
1659
|
+
...lbls,
|
|
1660
|
+
...lineEls
|
|
1661
|
+
]);
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
});
|
|
1665
|
+
var BarChart = (0, import_vue.defineComponent)({
|
|
1666
|
+
name: "VspBarChart",
|
|
1667
|
+
props: {
|
|
1668
|
+
data: { type: Array, default: () => [] },
|
|
1669
|
+
labels: { type: Array, default: void 0 },
|
|
1670
|
+
width: { type: Number, default: 620 },
|
|
1671
|
+
height: { type: Number, default: 240 },
|
|
1672
|
+
color: { type: String, default: "var(--accent)" }
|
|
1673
|
+
},
|
|
1674
|
+
setup(props) {
|
|
1675
|
+
return () => {
|
|
1676
|
+
const w = props.width;
|
|
1677
|
+
const height = props.height;
|
|
1678
|
+
const padL = 34;
|
|
1679
|
+
const padB = 26;
|
|
1680
|
+
const padT = 10;
|
|
1681
|
+
const innerW = Math.max(10, w - padL - 8);
|
|
1682
|
+
const innerH = height - padB - padT;
|
|
1683
|
+
const max = Math.max(...props.data, 0) * 1.15 || 1;
|
|
1684
|
+
const bw = innerW / (props.data.length || 1);
|
|
1685
|
+
const grid = [0, 0.5, 1].map((f, i) => {
|
|
1686
|
+
const y = padT + innerH - f * innerH;
|
|
1687
|
+
return (0, import_vue.h)("g", { key: "g" + i }, [
|
|
1688
|
+
(0, import_vue.h)("line", { x1: padL, x2: w - 8, y1: y, y2: y, stroke: "var(--grid-line)" }),
|
|
1689
|
+
(0, import_vue.h)(
|
|
1690
|
+
"text",
|
|
1691
|
+
{
|
|
1692
|
+
x: padL - 8,
|
|
1693
|
+
y: y + 3.5,
|
|
1694
|
+
"text-anchor": "end",
|
|
1695
|
+
"font-size": "10",
|
|
1696
|
+
fill: "var(--text-faint)",
|
|
1697
|
+
"font-family": "var(--font-mono)"
|
|
1698
|
+
},
|
|
1699
|
+
niceNum(Math.round(max * f))
|
|
1700
|
+
)
|
|
1701
|
+
]);
|
|
1702
|
+
});
|
|
1703
|
+
const bars = props.data.map((v, i) => {
|
|
1704
|
+
const bh = v / max * innerH;
|
|
1705
|
+
const x = padL + i * bw + bw * 0.18;
|
|
1706
|
+
const bwi = bw * 0.64;
|
|
1707
|
+
return (0, import_vue.h)("g", { key: "b" + i }, [
|
|
1708
|
+
(0, import_vue.h)("rect", {
|
|
1709
|
+
x,
|
|
1710
|
+
y: padT + innerH - bh,
|
|
1711
|
+
width: bwi,
|
|
1712
|
+
height: bh,
|
|
1713
|
+
rx: "4",
|
|
1714
|
+
fill: `color-mix(in oklab, ${props.color} 78%, transparent)`
|
|
1715
|
+
}),
|
|
1716
|
+
props.labels?.[i] != null ? (0, import_vue.h)(
|
|
1717
|
+
"text",
|
|
1718
|
+
{
|
|
1719
|
+
x: x + bwi / 2,
|
|
1720
|
+
y: height - 8,
|
|
1721
|
+
"text-anchor": "middle",
|
|
1722
|
+
"font-size": "10",
|
|
1723
|
+
fill: "var(--text-faint)",
|
|
1724
|
+
"font-family": "var(--font-mono)"
|
|
1725
|
+
},
|
|
1726
|
+
props.labels[i]
|
|
1727
|
+
) : null
|
|
1728
|
+
]);
|
|
1729
|
+
});
|
|
1730
|
+
return (0, import_vue.h)("svg", { width: w, height, style: { display: "block" } }, [...grid, ...bars]);
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
});
|
|
1273
1734
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1274
1735
|
0 && (module.exports = {
|
|
1275
1736
|
Accordion,
|
|
1276
1737
|
Alert,
|
|
1738
|
+
AreaChart,
|
|
1277
1739
|
Avatar,
|
|
1278
1740
|
AvatarGroup,
|
|
1279
1741
|
Badge,
|
|
1280
1742
|
Banner,
|
|
1743
|
+
BarChart,
|
|
1281
1744
|
Breadcrumb,
|
|
1282
1745
|
Button,
|
|
1283
1746
|
Card,
|
|
1284
1747
|
CardHead,
|
|
1285
1748
|
Checkbox,
|
|
1286
1749
|
CircularProgress,
|
|
1750
|
+
CopyButton,
|
|
1287
1751
|
DescriptionList,
|
|
1288
1752
|
Divider,
|
|
1289
1753
|
Donut,
|
|
1290
1754
|
EmptyState,
|
|
1291
1755
|
Field,
|
|
1292
1756
|
IconButton,
|
|
1757
|
+
InlineEdit,
|
|
1293
1758
|
Input,
|
|
1294
1759
|
Kbd,
|
|
1295
1760
|
NativeSelect,
|
|
1761
|
+
NumberStepper,
|
|
1762
|
+
OTPInput,
|
|
1296
1763
|
Pagination,
|
|
1297
1764
|
Progress,
|
|
1298
1765
|
Radio,
|
|
@@ -1310,6 +1777,8 @@ var StatCard = (0, import_vue.defineComponent)({
|
|
|
1310
1777
|
Tag,
|
|
1311
1778
|
Textarea,
|
|
1312
1779
|
Timeline,
|
|
1780
|
+
Tree,
|
|
1781
|
+
niceNum,
|
|
1313
1782
|
smoothPath
|
|
1314
1783
|
});
|
|
1315
1784
|
//# sourceMappingURL=index.cjs.map
|