@tapizlabs/ui 0.1.5 → 0.2.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.
- package/dist/index.d.ts +950 -8
- package/dist/index.js +2125 -149
- package/dist/index.js.map +1 -1
- package/dist/theme.css +261 -615
- package/package.json +6 -6
- package/FRAMEWORK_BOUNDARY.md +0 -47
package/dist/index.js
CHANGED
|
@@ -690,6 +690,8 @@ var variantClasses = {
|
|
|
690
690
|
hover:bg-[rgba(255,122,77,0.08)]`,
|
|
691
691
|
"outline-success": `${TOKEN_BASE} border border-[var(--color-good)] text-[var(--color-good)]
|
|
692
692
|
hover:bg-[rgba(77,214,163,0.08)]`,
|
|
693
|
+
brutal: `${TOKEN_BASE} border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-primary)]
|
|
694
|
+
shadow-[var(--tapiz-shadow-brutal)] font-bold hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[var(--tapiz-shadow-brutal-lg)]`,
|
|
693
695
|
link: "text-[var(--color-primary-300)] hover:text-[var(--color-primary-400)] disabled:opacity-40 disabled:cursor-not-allowed inline-flex items-center gap-1"
|
|
694
696
|
};
|
|
695
697
|
var sizeClasses = {
|
|
@@ -992,7 +994,7 @@ function Toast({ message, ok, durationMs = 5e3 }) {
|
|
|
992
994
|
const borderColor = ok ? "var(--color-good)" : "var(--color-warn)";
|
|
993
995
|
const accentColor = ok ? "var(--color-good)" : "var(--color-warn)";
|
|
994
996
|
return createPortal(
|
|
995
|
-
/* @__PURE__ */ jsx20("div", { className: "pointer-events-none fixed bottom-20 left-4 right-4 z-
|
|
997
|
+
/* @__PURE__ */ jsx20("div", { className: "pointer-events-none fixed bottom-20 left-4 right-4 z-9999 flex justify-center min-[600px]:bottom-auto min-[600px]:left-auto min-[600px]:right-5 min-[600px]:top-5 min-[600px]:justify-end", children: /* @__PURE__ */ jsxs13(
|
|
996
998
|
"div",
|
|
997
999
|
{
|
|
998
1000
|
className: `${transform} pointer-events-auto relative flex w-full max-w-sm items-center gap-2.5 overflow-hidden px-4 py-3 text-sm font-medium transition-all duration-300 sm:w-auto sm:max-w-xs`,
|
|
@@ -1095,33 +1097,82 @@ function DefaultErrorFallback({
|
|
|
1095
1097
|
label = "Tapiz UI \xB7 Runtime Error",
|
|
1096
1098
|
reloadLabel = "Reload page"
|
|
1097
1099
|
}) {
|
|
1098
|
-
return /* @__PURE__ */ jsxs16(
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
/* @__PURE__ */ jsx23(
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1100
|
+
return /* @__PURE__ */ jsxs16(
|
|
1101
|
+
"div",
|
|
1102
|
+
{
|
|
1103
|
+
className: "fixed inset-0 flex flex-col items-center justify-center overflow-hidden px-6",
|
|
1104
|
+
style: { background: "var(--color-ink-100)" },
|
|
1105
|
+
children: [
|
|
1106
|
+
/* @__PURE__ */ jsx23(GridBg, {}),
|
|
1107
|
+
/* @__PURE__ */ jsx23(Spotlight, { color: "rgba(255,100,100,0.06)" }),
|
|
1108
|
+
/* @__PURE__ */ jsxs16(
|
|
1109
|
+
"div",
|
|
1110
|
+
{
|
|
1111
|
+
className: "relative z-10 flex w-full max-w-sm flex-col items-center gap-6 text-center",
|
|
1112
|
+
style: { animation: "var(--animate-fade-in-up)" },
|
|
1113
|
+
children: [
|
|
1114
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
1115
|
+
/* @__PURE__ */ jsx23(
|
|
1116
|
+
"div",
|
|
1117
|
+
{
|
|
1118
|
+
className: "font-mono font-bold leading-none",
|
|
1119
|
+
style: { fontSize: "clamp(72px,16vw,120px)", color: "var(--color-border-hi)", letterSpacing: "-0.04em" },
|
|
1120
|
+
children: "500"
|
|
1121
|
+
}
|
|
1122
|
+
),
|
|
1123
|
+
/* @__PURE__ */ jsx23(
|
|
1124
|
+
"div",
|
|
1125
|
+
{
|
|
1126
|
+
className: "mt-1 h-0.5 w-full",
|
|
1127
|
+
style: { background: "linear-gradient(90deg,transparent,rgba(255,80,80,0.7),transparent)", opacity: 0.5 }
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] }),
|
|
1131
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1132
|
+
/* @__PURE__ */ jsx23("p", { className: "text-base font-semibold", style: { color: "var(--color-txt-1)" }, children: title }),
|
|
1133
|
+
/* @__PURE__ */ jsx23("p", { className: "font-mono text-[11px] leading-relaxed", style: { color: "var(--color-txt-3)" }, children: description })
|
|
1134
|
+
] }),
|
|
1135
|
+
/* @__PURE__ */ jsx23(
|
|
1136
|
+
"div",
|
|
1137
|
+
{
|
|
1138
|
+
className: "font-mono text-[9px] uppercase px-2 py-1",
|
|
1139
|
+
style: {
|
|
1140
|
+
letterSpacing: ".2em",
|
|
1141
|
+
color: "rgba(255,80,80,0.9)",
|
|
1142
|
+
border: "1px solid rgba(255,80,80,0.25)",
|
|
1143
|
+
background: "rgba(255,80,80,0.05)"
|
|
1144
|
+
},
|
|
1145
|
+
children: label
|
|
1146
|
+
}
|
|
1147
|
+
),
|
|
1148
|
+
/* @__PURE__ */ jsx23("div", { className: "w-full", children: /* @__PURE__ */ jsxs16(
|
|
1149
|
+
"button",
|
|
1150
|
+
{
|
|
1151
|
+
type: "button",
|
|
1152
|
+
onClick: () => window.location.reload(),
|
|
1153
|
+
style: {
|
|
1154
|
+
width: "100%",
|
|
1155
|
+
padding: "10px",
|
|
1156
|
+
fontSize: "12px",
|
|
1157
|
+
background: "var(--color-primary-300)",
|
|
1158
|
+
color: "var(--color-ink-100)",
|
|
1159
|
+
border: "none",
|
|
1160
|
+
cursor: "pointer",
|
|
1161
|
+
fontFamily: "var(--font-mono)",
|
|
1162
|
+
letterSpacing: "0.05em"
|
|
1163
|
+
},
|
|
1164
|
+
children: [
|
|
1165
|
+
reloadLabel,
|
|
1166
|
+
" \u2192"
|
|
1167
|
+
]
|
|
1168
|
+
}
|
|
1169
|
+
) })
|
|
1170
|
+
]
|
|
1171
|
+
}
|
|
1172
|
+
)
|
|
1173
|
+
]
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1125
1176
|
}
|
|
1126
1177
|
function GridBg() {
|
|
1127
1178
|
return /* @__PURE__ */ jsx23("div", { className: "pointer-events-none absolute inset-0 opacity-50 bg-[linear-gradient(var(--color-border)_1px,transparent_1px),linear-gradient(90deg,var(--color-border)_1px,transparent_1px)] bg-size-[32px_32px]" });
|
|
@@ -1312,11 +1363,12 @@ function Tooltip({ text, children, position = "top", align = "center", width = "
|
|
|
1312
1363
|
/* @__PURE__ */ jsxs19(
|
|
1313
1364
|
"span",
|
|
1314
1365
|
{
|
|
1315
|
-
className: `pointer-events-none absolute ${alignClass}
|
|
1366
|
+
className: `pointer-events-none absolute ${alignClass} ${width} w-max px-2.5 py-1.5
|
|
1316
1367
|
text-center text-[11px] leading-snug
|
|
1317
1368
|
opacity-0 group-hover:opacity-100 transition-opacity duration-150
|
|
1318
1369
|
${position === "top" ? "bottom-full mb-2" : "top-full mt-2"}`,
|
|
1319
1370
|
style: {
|
|
1371
|
+
zIndex: 60,
|
|
1320
1372
|
background: "var(--color-ink-300)",
|
|
1321
1373
|
border: "1px solid var(--color-border-hi)",
|
|
1322
1374
|
color: "var(--color-txt-2)",
|
|
@@ -1341,11 +1393,43 @@ function Tooltip({ text, children, position = "top", align = "center", width = "
|
|
|
1341
1393
|
|
|
1342
1394
|
// src/components/shared/Card.tsx
|
|
1343
1395
|
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1344
|
-
|
|
1345
|
-
|
|
1396
|
+
var variantClasses2 = {
|
|
1397
|
+
surface: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] shadow-[var(--tapiz-shadow-sm)]",
|
|
1398
|
+
raised: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-raised)] shadow-[var(--tapiz-shadow-md)]",
|
|
1399
|
+
outlined: "border border-[var(--tapiz-border-strong)] bg-transparent",
|
|
1400
|
+
brutal: "border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] shadow-[var(--tapiz-shadow-brutal)]",
|
|
1401
|
+
glass: "border border-[var(--tapiz-border-subtle)] bg-[color-mix(in_srgb,var(--tapiz-bg-surface)_78%,transparent)] shadow-[var(--tapiz-shadow-md)] backdrop-blur-xl"
|
|
1402
|
+
};
|
|
1403
|
+
var paddingClasses = {
|
|
1404
|
+
none: "p-0",
|
|
1405
|
+
sm: "p-3",
|
|
1406
|
+
md: "p-5",
|
|
1407
|
+
lg: "p-6"
|
|
1408
|
+
};
|
|
1409
|
+
function Card({
|
|
1410
|
+
children,
|
|
1411
|
+
className = "",
|
|
1412
|
+
hover = false,
|
|
1413
|
+
style,
|
|
1414
|
+
variant = "surface",
|
|
1415
|
+
padding = "md"
|
|
1416
|
+
}) {
|
|
1417
|
+
return /* @__PURE__ */ jsx27(
|
|
1418
|
+
"div",
|
|
1419
|
+
{
|
|
1420
|
+
className: [
|
|
1421
|
+
variantClasses2[variant],
|
|
1422
|
+
paddingClasses[padding],
|
|
1423
|
+
hover ? "card-hover" : "",
|
|
1424
|
+
className
|
|
1425
|
+
].filter(Boolean).join(" "),
|
|
1426
|
+
style,
|
|
1427
|
+
children
|
|
1428
|
+
}
|
|
1429
|
+
);
|
|
1346
1430
|
}
|
|
1347
1431
|
function CardHeader({ children, className = "" }) {
|
|
1348
|
-
return /* @__PURE__ */ jsx27("div", { className: `border-b border-border px-5 py-3 ${className}`, children });
|
|
1432
|
+
return /* @__PURE__ */ jsx27("div", { className: `border-b border-[var(--tapiz-border-subtle)] px-5 py-3 ${className}`, children });
|
|
1349
1433
|
}
|
|
1350
1434
|
function CardBody({ children, className = "" }) {
|
|
1351
1435
|
return /* @__PURE__ */ jsx27("div", { className: `p-5 ${className}`, children });
|
|
@@ -1432,18 +1516,19 @@ function SkeletonPageHeader() {
|
|
|
1432
1516
|
|
|
1433
1517
|
// src/components/shared/Badge.tsx
|
|
1434
1518
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1435
|
-
var
|
|
1436
|
-
default: "border-
|
|
1437
|
-
success: "border-
|
|
1438
|
-
warning: "border-
|
|
1439
|
-
danger: "border-
|
|
1519
|
+
var variantClasses3 = {
|
|
1520
|
+
default: "border-[var(--tapiz-accent)] text-[var(--tapiz-accent)] bg-[var(--tapiz-accent-soft)]",
|
|
1521
|
+
success: "border-[var(--tapiz-success)] text-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)]",
|
|
1522
|
+
warning: "border-[var(--tapiz-warning)] text-[var(--tapiz-warning)] bg-[var(--tapiz-warning-soft)]",
|
|
1523
|
+
danger: "border-[var(--tapiz-danger)] text-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)]",
|
|
1524
|
+
info: "border-[var(--tapiz-info)] text-[var(--tapiz-info)] bg-[var(--tapiz-info-soft)]",
|
|
1440
1525
|
muted: "border-txt-3 text-txt-3"
|
|
1441
1526
|
};
|
|
1442
1527
|
function Badge({ children, variant = "default", className = "" }) {
|
|
1443
1528
|
return /* @__PURE__ */ jsx30(
|
|
1444
1529
|
"span",
|
|
1445
1530
|
{
|
|
1446
|
-
className: `inline-flex items-center border px-2 py-0.5 font-mono text-[9px] font-bold uppercase tracking-widest ${
|
|
1531
|
+
className: `inline-flex items-center border px-2 py-0.5 font-mono text-[9px] font-bold uppercase tracking-widest ${variantClasses3[variant]} ${className}`,
|
|
1447
1532
|
children
|
|
1448
1533
|
}
|
|
1449
1534
|
);
|
|
@@ -1477,7 +1562,7 @@ function InfoBanner(props) {
|
|
|
1477
1562
|
const { text, variant = "info", className: className2 = "" } = props;
|
|
1478
1563
|
const styles = variant === "warn" ? "bg-warn/8 border-warn/25 text-warn" : variant === "lock" ? "bg-warn/8 border-warn/30 text-warn" : "bg-primary-500/10 border-primary-100 text-primary-500";
|
|
1479
1564
|
const icon = variant === "lock" ? /* @__PURE__ */ jsx32(LockIcon, { size: 14, className: "mt-1 shrink-0" }) : /* @__PURE__ */ jsx32(Info, { size: 14, className: "mt-1 shrink-0" });
|
|
1480
|
-
return /* @__PURE__ */ jsxs22("div", { className: `flex items-start gap-2 border px-3 py-2.5 text-[13px] ${styles} ${className2}`, children: [
|
|
1565
|
+
return /* @__PURE__ */ jsxs22("div", { className: `app-info-banner flex items-start gap-2 border px-3 py-2.5 text-[13px] ${styles} ${className2}`, children: [
|
|
1481
1566
|
icon,
|
|
1482
1567
|
/* @__PURE__ */ jsx32("p", { style: { fontFamily: "var(--font-mono)" }, children: text })
|
|
1483
1568
|
] });
|
|
@@ -1486,7 +1571,7 @@ function InfoBanner(props) {
|
|
|
1486
1571
|
return /* @__PURE__ */ jsxs22(
|
|
1487
1572
|
"div",
|
|
1488
1573
|
{
|
|
1489
|
-
className: `px-4 py-3 ${className}`,
|
|
1574
|
+
className: `app-info-banner px-4 py-3 ${className}`,
|
|
1490
1575
|
style: {
|
|
1491
1576
|
background: "rgba(94,231,255,0.04)",
|
|
1492
1577
|
border: "1px solid rgba(94,231,255,0.12)",
|
|
@@ -1509,27 +1594,103 @@ function InfoBanner(props) {
|
|
|
1509
1594
|
|
|
1510
1595
|
// src/components/shared/PageHeader.tsx
|
|
1511
1596
|
import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1512
|
-
function PageHeader({
|
|
1513
|
-
|
|
1597
|
+
function PageHeader({
|
|
1598
|
+
title,
|
|
1599
|
+
subtitle,
|
|
1600
|
+
description,
|
|
1601
|
+
action,
|
|
1602
|
+
actions,
|
|
1603
|
+
icon,
|
|
1604
|
+
banner,
|
|
1605
|
+
breadcrumbs,
|
|
1606
|
+
meta,
|
|
1607
|
+
className = "",
|
|
1608
|
+
variant = "default"
|
|
1609
|
+
}) {
|
|
1610
|
+
const resolvedActions = actions ?? action;
|
|
1611
|
+
const variantClass = variant === "brutal" ? "border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] p-5 shadow-[var(--tapiz-shadow-brutal)]" : variant === "enterprise" ? "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-5 shadow-[var(--tapiz-shadow-sm)]" : "border-b border-[var(--tapiz-border-subtle)] pb-4";
|
|
1612
|
+
return /* @__PURE__ */ jsxs23("div", { className: `page-header mb-5 flex flex-col gap-3 animate-fade-in-up ${variantClass} ${className}`.trim(), children: [
|
|
1613
|
+
breadcrumbs ? /* @__PURE__ */ jsx33("div", { className: "font-mono text-[10px] uppercase tracking-[0.16em] text-[var(--tapiz-text-muted)]", children: breadcrumbs }) : null,
|
|
1614
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
1615
|
+
/* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
|
|
1616
|
+
subtitle ? /* @__PURE__ */ jsx33("div", { className: "kicker mb-1.5", children: subtitle }) : null,
|
|
1617
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2.5", children: [
|
|
1618
|
+
icon ? /* @__PURE__ */ jsx33("span", { className: "text-[var(--tapiz-accent)]", children: icon }) : null,
|
|
1619
|
+
/* @__PURE__ */ jsx33("h2", { className: "font-(--font-display) text-[22px] tracking-[-0.03em] text-[var(--tapiz-text-primary)] md:text-[26px]", children: title })
|
|
1620
|
+
] }),
|
|
1621
|
+
description ? /* @__PURE__ */ jsx33("div", { className: "mt-2 max-w-3xl text-sm leading-6 text-[var(--tapiz-text-muted)]", children: description }) : null,
|
|
1622
|
+
meta ? /* @__PURE__ */ jsx33("div", { className: "mt-3 font-mono text-[11px] text-[var(--tapiz-text-disabled)]", children: meta }) : null
|
|
1623
|
+
] }),
|
|
1624
|
+
resolvedActions ? /* @__PURE__ */ jsx33("div", { className: "flex shrink-0 flex-wrap gap-2", children: resolvedActions }) : null
|
|
1625
|
+
] }),
|
|
1626
|
+
banner ? banner : null
|
|
1627
|
+
] });
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// src/components/shared/MetricCard.tsx
|
|
1631
|
+
import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1632
|
+
var trendClasses = {
|
|
1633
|
+
positive: "border-[var(--tapiz-success)] text-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)]",
|
|
1634
|
+
negative: "border-[var(--tapiz-danger)] text-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)]",
|
|
1635
|
+
warning: "border-[var(--tapiz-warning)] text-[var(--tapiz-warning)] bg-[var(--tapiz-warning-soft)]",
|
|
1636
|
+
neutral: "border-[var(--tapiz-border-strong)] text-[var(--tapiz-text-muted)] bg-[var(--tapiz-bg-surface-muted)]"
|
|
1637
|
+
};
|
|
1638
|
+
function MetricCard({
|
|
1639
|
+
label,
|
|
1640
|
+
value,
|
|
1641
|
+
description,
|
|
1642
|
+
icon,
|
|
1643
|
+
trend,
|
|
1644
|
+
trendTone = "neutral",
|
|
1645
|
+
className = "",
|
|
1646
|
+
variant = "surface"
|
|
1647
|
+
}) {
|
|
1648
|
+
return /* @__PURE__ */ jsxs24(Card, { variant, padding: "md", hover: true, className: `relative overflow-hidden ${className}`, children: [
|
|
1649
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-start justify-between gap-4", children: [
|
|
1650
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0", children: [
|
|
1651
|
+
/* @__PURE__ */ jsx34("p", { className: "font-mono text-[10px] font-bold uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: label }),
|
|
1652
|
+
/* @__PURE__ */ jsx34("div", { className: "mt-2 font-display text-3xl font-semibold tracking-[-0.05em] text-[var(--tapiz-text-primary)]", children: value })
|
|
1653
|
+
] }),
|
|
1654
|
+
icon ? /* @__PURE__ */ jsx34("div", { className: "grid h-10 w-10 shrink-0 place-items-center border border-[var(--tapiz-border-strong)] bg-[var(--color-icon-bg)] text-[var(--tapiz-accent)]", children: icon }) : null
|
|
1655
|
+
] }),
|
|
1656
|
+
description || trend ? /* @__PURE__ */ jsxs24("div", { className: "mt-4 flex flex-wrap items-center gap-2", children: [
|
|
1657
|
+
trend ? /* @__PURE__ */ jsx34("span", { className: `inline-flex border px-2 py-0.5 font-mono text-[10px] font-bold uppercase tracking-widest ${trendClasses[trendTone]}`, children: trend }) : null,
|
|
1658
|
+
description ? /* @__PURE__ */ jsx34("p", { className: "text-xs text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
1659
|
+
] }) : null
|
|
1660
|
+
] });
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
// src/components/shared/StatGrid.tsx
|
|
1664
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1665
|
+
function StatGrid({ children, className = "", minColumnWidth = "14rem" }) {
|
|
1666
|
+
return /* @__PURE__ */ jsx35(
|
|
1514
1667
|
"div",
|
|
1515
1668
|
{
|
|
1516
|
-
className: `
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
subtitle ? /* @__PURE__ */ jsx33("div", { className: "kicker mb-1.5 text-primary-300!", children: subtitle }) : null,
|
|
1520
|
-
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2.5", children: [
|
|
1521
|
-
icon ? /* @__PURE__ */ jsx33("span", { className: "text-primary-300", children: icon }) : null,
|
|
1522
|
-
/* @__PURE__ */ jsx33("h2", { className: "font-(--font-display) text-[22px] tracking-[-0.03em] text-txt-1", children: title })
|
|
1523
|
-
] })
|
|
1524
|
-
] }),
|
|
1525
|
-
action ? /* @__PURE__ */ jsx33("div", { children: action }) : null
|
|
1526
|
-
]
|
|
1669
|
+
className: `grid gap-4 ${className}`,
|
|
1670
|
+
style: { gridTemplateColumns: `repeat(auto-fit, minmax(${minColumnWidth}, 1fr))` },
|
|
1671
|
+
children
|
|
1527
1672
|
}
|
|
1528
1673
|
);
|
|
1529
1674
|
}
|
|
1530
1675
|
|
|
1676
|
+
// src/components/shared/SectionCard.tsx
|
|
1677
|
+
import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1678
|
+
function SectionCard({ title, eyebrow, description, action, children, className = "" }) {
|
|
1679
|
+
return /* @__PURE__ */ jsxs25(Card, { variant: "surface", padding: "none", className, children: [
|
|
1680
|
+
title || eyebrow || description || action ? /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-3 border-b border-[var(--tapiz-border-subtle)] px-5 py-4 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
1681
|
+
/* @__PURE__ */ jsxs25("div", { className: "min-w-0", children: [
|
|
1682
|
+
eyebrow ? /* @__PURE__ */ jsx36("div", { className: "kicker mb-1", children: eyebrow }) : null,
|
|
1683
|
+
title ? /* @__PURE__ */ jsx36("h3", { className: "text-lg font-semibold text-[var(--tapiz-text-primary)]", children: title }) : null,
|
|
1684
|
+
description ? /* @__PURE__ */ jsx36("p", { className: "mt-1 text-sm text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
1685
|
+
] }),
|
|
1686
|
+
action ? /* @__PURE__ */ jsx36("div", { className: "shrink-0", children: action }) : null
|
|
1687
|
+
] }) : null,
|
|
1688
|
+
/* @__PURE__ */ jsx36("div", { className: "p-5", children })
|
|
1689
|
+
] });
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1531
1692
|
// src/components/shared/SearchInput.tsx
|
|
1532
|
-
import { jsx as
|
|
1693
|
+
import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1533
1694
|
function SearchInput({
|
|
1534
1695
|
value,
|
|
1535
1696
|
onChange,
|
|
@@ -1542,9 +1703,9 @@ function SearchInput({
|
|
|
1542
1703
|
clearTitle = "Clear search",
|
|
1543
1704
|
...props
|
|
1544
1705
|
}) {
|
|
1545
|
-
return /* @__PURE__ */
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
/* @__PURE__ */
|
|
1706
|
+
return /* @__PURE__ */ jsxs26("div", { className: `relative ${wrapperClassName}`.trim(), style: wrapperStyle, children: [
|
|
1707
|
+
/* @__PURE__ */ jsx37("span", { className: `pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 ${iconClassName}`.trim(), children: /* @__PURE__ */ jsx37(Search, { size: 15 }) }),
|
|
1708
|
+
/* @__PURE__ */ jsx37(
|
|
1548
1709
|
Input,
|
|
1549
1710
|
{
|
|
1550
1711
|
...props,
|
|
@@ -1555,21 +1716,21 @@ function SearchInput({
|
|
|
1555
1716
|
className: `pl-9 ${inputClassName}`.trim()
|
|
1556
1717
|
}
|
|
1557
1718
|
),
|
|
1558
|
-
clearable && value ? /* @__PURE__ */
|
|
1719
|
+
clearable && value ? /* @__PURE__ */ jsx37(
|
|
1559
1720
|
"button",
|
|
1560
1721
|
{
|
|
1561
1722
|
type: "button",
|
|
1562
1723
|
onClick: () => onChange(""),
|
|
1563
1724
|
className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-lg p-1 text-txt-4 transition-colors hover:bg-ink-300 hover:text-txt-2",
|
|
1564
1725
|
title: clearTitle,
|
|
1565
|
-
children: /* @__PURE__ */
|
|
1726
|
+
children: /* @__PURE__ */ jsx37(X, { size: 14 })
|
|
1566
1727
|
}
|
|
1567
1728
|
) : null
|
|
1568
1729
|
] });
|
|
1569
1730
|
}
|
|
1570
1731
|
|
|
1571
1732
|
// src/components/shared/Pagination.tsx
|
|
1572
|
-
import { jsx as
|
|
1733
|
+
import { jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1573
1734
|
function getPageNumbers(page, totalPages) {
|
|
1574
1735
|
if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
1575
1736
|
const pages = [1];
|
|
@@ -1593,10 +1754,10 @@ function Pagination({ page, totalPages, onChange, totalItems, pageSize, labels }
|
|
|
1593
1754
|
const pageNumbers = getPageNumbers(page, totalPages);
|
|
1594
1755
|
const from = pageSize ? (page - 1) * pageSize + 1 : null;
|
|
1595
1756
|
const to = pageSize && totalItems ? Math.min(page * pageSize, totalItems) : null;
|
|
1596
|
-
return /* @__PURE__ */
|
|
1597
|
-
totalItems != null && from != null && to != null ? /* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
/* @__PURE__ */
|
|
1757
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center justify-between gap-3 border-t border-border pt-3 sm:flex-row", children: [
|
|
1758
|
+
totalItems != null && from != null && to != null ? /* @__PURE__ */ jsx38("span", { className: "order-2 font-mono text-[12px] text-txt-4 sm:order-1", children: copy.showing({ from, to, total: totalItems }) }) : /* @__PURE__ */ jsx38("span", { className: "order-2 font-mono text-[11px] text-txt-4 sm:order-1", children: copy.page({ page, totalPages }) }),
|
|
1759
|
+
/* @__PURE__ */ jsxs27("div", { className: "order-1 flex items-center gap-1 sm:order-2", children: [
|
|
1760
|
+
/* @__PURE__ */ jsxs27(
|
|
1600
1761
|
"button",
|
|
1601
1762
|
{
|
|
1602
1763
|
type: "button",
|
|
@@ -1605,13 +1766,13 @@ function Pagination({ page, totalPages, onChange, totalItems, pageSize, labels }
|
|
|
1605
1766
|
title: copy.prevTitle,
|
|
1606
1767
|
className: "flex items-center gap-1 border border-border px-2.5 py-1.5 font-mono text-[11px] text-txt-3 transition-colors hover:border-border-hi hover:text-txt-1 disabled:cursor-not-allowed disabled:opacity-30",
|
|
1607
1768
|
children: [
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1769
|
+
/* @__PURE__ */ jsx38(ChevronLeft, { size: 12 }),
|
|
1770
|
+
/* @__PURE__ */ jsx38("span", { className: "hidden sm:inline", children: copy.prev })
|
|
1610
1771
|
]
|
|
1611
1772
|
}
|
|
1612
1773
|
),
|
|
1613
|
-
/* @__PURE__ */
|
|
1614
|
-
(entry, index) => entry === "\u2026" ? /* @__PURE__ */
|
|
1774
|
+
/* @__PURE__ */ jsx38("div", { className: "flex items-center gap-1", children: pageNumbers.map(
|
|
1775
|
+
(entry, index) => entry === "\u2026" ? /* @__PURE__ */ jsx38("span", { className: "w-7 text-center font-mono text-[11px] text-txt-4", children: "\u2026" }, `ellipsis-${index}`) : /* @__PURE__ */ jsx38(
|
|
1615
1776
|
"button",
|
|
1616
1777
|
{
|
|
1617
1778
|
type: "button",
|
|
@@ -1622,7 +1783,7 @@ function Pagination({ page, totalPages, onChange, totalItems, pageSize, labels }
|
|
|
1622
1783
|
entry
|
|
1623
1784
|
)
|
|
1624
1785
|
) }),
|
|
1625
|
-
/* @__PURE__ */
|
|
1786
|
+
/* @__PURE__ */ jsxs27(
|
|
1626
1787
|
"button",
|
|
1627
1788
|
{
|
|
1628
1789
|
type: "button",
|
|
@@ -1631,8 +1792,8 @@ function Pagination({ page, totalPages, onChange, totalItems, pageSize, labels }
|
|
|
1631
1792
|
title: copy.nextTitle,
|
|
1632
1793
|
className: "flex items-center gap-1 border border-border px-2.5 py-1.5 font-mono text-[10px] text-txt-3 transition-colors hover:border-border-hi hover:text-txt-1 disabled:cursor-not-allowed disabled:opacity-30",
|
|
1633
1794
|
children: [
|
|
1634
|
-
/* @__PURE__ */
|
|
1635
|
-
/* @__PURE__ */
|
|
1795
|
+
/* @__PURE__ */ jsx38("span", { className: "hidden sm:inline", children: copy.next }),
|
|
1796
|
+
/* @__PURE__ */ jsx38(ChevronRight, { size: 12 })
|
|
1636
1797
|
]
|
|
1637
1798
|
}
|
|
1638
1799
|
)
|
|
@@ -1641,30 +1802,32 @@ function Pagination({ page, totalPages, onChange, totalItems, pageSize, labels }
|
|
|
1641
1802
|
}
|
|
1642
1803
|
|
|
1643
1804
|
// src/components/shared/SectionTitle.tsx
|
|
1644
|
-
import { jsx as
|
|
1805
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
1645
1806
|
function SectionTitle({ children, className = "" }) {
|
|
1646
|
-
return /* @__PURE__ */
|
|
1807
|
+
return /* @__PURE__ */ jsx39("h3", { className: `mb-1 text-sm font-semibold text-txt-1 ${className}`.trim(), children });
|
|
1647
1808
|
}
|
|
1648
1809
|
|
|
1649
1810
|
// src/components/shared/StatusBadge.tsx
|
|
1650
|
-
import { jsx as
|
|
1651
|
-
var BASE = "inline-flex items-center border px-2 py-0.5 font-mono text-[9px] font-
|
|
1811
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
1812
|
+
var BASE = "inline-flex items-center border px-2 py-0.5 font-mono text-[9px] font-bold uppercase tracking-[0.15em]";
|
|
1652
1813
|
var variantStyles = {
|
|
1653
|
-
default: "border-border-
|
|
1654
|
-
active: "border-
|
|
1655
|
-
success: "border-
|
|
1656
|
-
inactive: "border-
|
|
1657
|
-
warning: "border-
|
|
1658
|
-
danger: "border-
|
|
1659
|
-
|
|
1814
|
+
default: "border-[var(--tapiz-border-strong)] text-[var(--tapiz-text-secondary)] bg-[var(--tapiz-bg-surface-muted)]",
|
|
1815
|
+
active: "border-[var(--tapiz-accent)] text-[var(--tapiz-accent)] bg-[var(--tapiz-accent-soft)]",
|
|
1816
|
+
success: "border-[var(--tapiz-success)] text-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)]",
|
|
1817
|
+
inactive: "border-[var(--tapiz-text-disabled)] text-[var(--tapiz-text-disabled)] bg-transparent",
|
|
1818
|
+
warning: "border-[var(--tapiz-warning)] text-[var(--tapiz-warning)] bg-[var(--tapiz-warning-soft)]",
|
|
1819
|
+
danger: "border-[var(--tapiz-danger)] text-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)]",
|
|
1820
|
+
info: "border-[var(--tapiz-info)] text-[var(--tapiz-info)] bg-[var(--tapiz-info-soft)]",
|
|
1821
|
+
pending: "border-[var(--tapiz-text-muted)] text-[var(--tapiz-text-muted)] bg-transparent"
|
|
1660
1822
|
};
|
|
1661
1823
|
function StatusBadge({ label, variant = "default", className = "" }) {
|
|
1662
|
-
return /* @__PURE__ */
|
|
1824
|
+
return /* @__PURE__ */ jsx40("span", { className: `${BASE} ${variantStyles[variant]} ${className}`.trim(), children: label });
|
|
1663
1825
|
}
|
|
1664
1826
|
|
|
1665
1827
|
// src/components/shared/ActionMenu.tsx
|
|
1666
|
-
import { useEffect as useEffect2, useRef as useRef2, useState as useState5 } from "react";
|
|
1667
|
-
import {
|
|
1828
|
+
import { useEffect as useEffect2, useLayoutEffect, useRef as useRef2, useState as useState5 } from "react";
|
|
1829
|
+
import { createPortal as createPortal4 } from "react-dom";
|
|
1830
|
+
import { Fragment, jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1668
1831
|
var defaultMenuStyle = {
|
|
1669
1832
|
background: "var(--color-ink-200)",
|
|
1670
1833
|
border: "1px solid var(--color-border-hi)",
|
|
@@ -1680,67 +1843,131 @@ function ActionMenu({
|
|
|
1680
1843
|
buttonSize = "sm",
|
|
1681
1844
|
buttonVariant = "secondary",
|
|
1682
1845
|
buttonClassName = "",
|
|
1683
|
-
menuClassName
|
|
1846
|
+
menuClassName,
|
|
1684
1847
|
menuStyle,
|
|
1685
1848
|
fullWidth = false,
|
|
1686
1849
|
closeLabel
|
|
1687
1850
|
}) {
|
|
1688
1851
|
const [open, setOpen] = useState5(false);
|
|
1689
|
-
const
|
|
1852
|
+
const [pos, setPos] = useState5(null);
|
|
1853
|
+
const btnRef = useRef2(null);
|
|
1854
|
+
const menuRef = useRef2(null);
|
|
1855
|
+
useLayoutEffect(() => {
|
|
1856
|
+
if (!open || !btnRef.current) return;
|
|
1857
|
+
const updatePosition = () => {
|
|
1858
|
+
const buttonElement = btnRef.current;
|
|
1859
|
+
if (!buttonElement) return;
|
|
1860
|
+
const rect = buttonElement.getBoundingClientRect();
|
|
1861
|
+
const viewportPadding = 8;
|
|
1862
|
+
const menuOffset = 4;
|
|
1863
|
+
const menuW = Math.min(320, window.innerWidth - viewportPadding * 2);
|
|
1864
|
+
const left = Math.max(
|
|
1865
|
+
viewportPadding,
|
|
1866
|
+
Math.min(rect.right - menuW, window.innerWidth - menuW - viewportPadding)
|
|
1867
|
+
);
|
|
1868
|
+
const estimatedMenuHeight = Math.min(320, items.length * 44 + 16);
|
|
1869
|
+
const spaceAbove = Math.max(0, rect.top - viewportPadding - menuOffset);
|
|
1870
|
+
const spaceBelow = Math.max(0, window.innerHeight - rect.bottom - viewportPadding - menuOffset);
|
|
1871
|
+
const preferBelow = spaceBelow >= estimatedMenuHeight || spaceBelow >= spaceAbove;
|
|
1872
|
+
if (preferBelow) {
|
|
1873
|
+
setPos({
|
|
1874
|
+
top: Math.min(rect.bottom + menuOffset, window.innerHeight - viewportPadding),
|
|
1875
|
+
left,
|
|
1876
|
+
width: menuW,
|
|
1877
|
+
maxHeight: Math.max(120, spaceBelow)
|
|
1878
|
+
});
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
setPos({
|
|
1882
|
+
bottom: Math.max(window.innerHeight - rect.top + menuOffset, viewportPadding),
|
|
1883
|
+
left,
|
|
1884
|
+
width: menuW,
|
|
1885
|
+
maxHeight: Math.max(120, spaceAbove)
|
|
1886
|
+
});
|
|
1887
|
+
};
|
|
1888
|
+
updatePosition();
|
|
1889
|
+
window.addEventListener("resize", updatePosition);
|
|
1890
|
+
document.addEventListener("scroll", updatePosition, true);
|
|
1891
|
+
return () => {
|
|
1892
|
+
window.removeEventListener("resize", updatePosition);
|
|
1893
|
+
document.removeEventListener("scroll", updatePosition, true);
|
|
1894
|
+
};
|
|
1895
|
+
}, [items.length, open]);
|
|
1690
1896
|
useEffect2(() => {
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1897
|
+
if (!open) return;
|
|
1898
|
+
function handle(e) {
|
|
1899
|
+
if (e instanceof KeyboardEvent) {
|
|
1900
|
+
if (e.key === "Escape") setOpen(false);
|
|
1901
|
+
return;
|
|
1694
1902
|
}
|
|
1903
|
+
const target = e.target;
|
|
1904
|
+
if (btnRef.current?.contains(target) || menuRef.current?.contains(target)) return;
|
|
1905
|
+
setOpen(false);
|
|
1695
1906
|
}
|
|
1696
|
-
document.addEventListener("mousedown",
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1907
|
+
document.addEventListener("mousedown", handle);
|
|
1908
|
+
document.addEventListener("keydown", handle);
|
|
1909
|
+
return () => {
|
|
1910
|
+
document.removeEventListener("mousedown", handle);
|
|
1911
|
+
document.removeEventListener("keydown", handle);
|
|
1912
|
+
};
|
|
1913
|
+
}, [open]);
|
|
1914
|
+
const menuNode = open && pos ? /* @__PURE__ */ jsxs28(Fragment, { children: [
|
|
1915
|
+
/* @__PURE__ */ jsx41("div", { className: "fixed inset-0 z-9998", onClick: () => setOpen(false) }),
|
|
1916
|
+
/* @__PURE__ */ jsx41(
|
|
1917
|
+
"div",
|
|
1918
|
+
{
|
|
1919
|
+
ref: menuRef,
|
|
1920
|
+
className: menuClassName ?? "overflow-auto",
|
|
1921
|
+
style: {
|
|
1922
|
+
position: "fixed",
|
|
1923
|
+
top: pos.top !== void 0 ? pos.top : void 0,
|
|
1924
|
+
bottom: pos.bottom !== void 0 ? pos.bottom : void 0,
|
|
1925
|
+
left: pos.left,
|
|
1926
|
+
width: pos.width,
|
|
1927
|
+
maxWidth: "calc(100vw - 16px)",
|
|
1928
|
+
zIndex: 9999,
|
|
1929
|
+
...defaultMenuStyle,
|
|
1930
|
+
maxHeight: pos.maxHeight ?? defaultMenuStyle.maxHeight,
|
|
1931
|
+
...menuStyle
|
|
1932
|
+
},
|
|
1933
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs28("div", { children: [
|
|
1934
|
+
index > 0 && item.danger ? /* @__PURE__ */ jsx41("div", { style: { borderTop: "1px solid var(--color-border)" } }) : null,
|
|
1935
|
+
/* @__PURE__ */ jsxs28(
|
|
1936
|
+
"button",
|
|
1937
|
+
{
|
|
1938
|
+
type: "button",
|
|
1939
|
+
className: itemBaseClass,
|
|
1940
|
+
style: { color: item.danger ? "var(--color-warn)" : "var(--color-txt-2)" },
|
|
1941
|
+
disabled: item.disabled || item.loading,
|
|
1942
|
+
onClick: () => {
|
|
1943
|
+
setOpen(false);
|
|
1944
|
+
item.onSelect();
|
|
1945
|
+
},
|
|
1946
|
+
children: [
|
|
1947
|
+
item.loading ? /* @__PURE__ */ jsx41(Spinner, { color: "text-[var(--color-txt-3)]" }) : /* @__PURE__ */ jsx41("span", { className: item.danger ? "shrink-0 text-warn" : "shrink-0 text-primary-300", children: item.icon }),
|
|
1948
|
+
/* @__PURE__ */ jsx41("span", { children: item.label })
|
|
1949
|
+
]
|
|
1950
|
+
}
|
|
1951
|
+
)
|
|
1952
|
+
] }, item.key))
|
|
1953
|
+
}
|
|
1954
|
+
)
|
|
1955
|
+
] }) : null;
|
|
1956
|
+
return /* @__PURE__ */ jsxs28("div", { ref: btnRef, className: fullWidth ? "relative w-full" : "relative inline-block max-w-full", children: [
|
|
1957
|
+
/* @__PURE__ */ jsx41(
|
|
1701
1958
|
Button,
|
|
1702
1959
|
{
|
|
1703
1960
|
size: buttonSize,
|
|
1704
1961
|
variant: buttonVariant,
|
|
1705
1962
|
icon,
|
|
1706
|
-
iconRight: /* @__PURE__ */
|
|
1963
|
+
iconRight: /* @__PURE__ */ jsx41(ChevronDown, { size: 11 }),
|
|
1707
1964
|
onClick: () => setOpen((value) => !value),
|
|
1708
1965
|
className: buttonClassName,
|
|
1709
1966
|
fullWidth,
|
|
1710
1967
|
children: label
|
|
1711
1968
|
}
|
|
1712
1969
|
),
|
|
1713
|
-
|
|
1714
|
-
/* @__PURE__ */ jsx38(
|
|
1715
|
-
"button",
|
|
1716
|
-
{
|
|
1717
|
-
type: "button",
|
|
1718
|
-
className: "fixed inset-0 z-40 bg-black/10 backdrop-blur-[3px]",
|
|
1719
|
-
"aria-label": closeLabel ?? label,
|
|
1720
|
-
onClick: () => setOpen(false)
|
|
1721
|
-
}
|
|
1722
|
-
),
|
|
1723
|
-
/* @__PURE__ */ jsx38("div", { className: menuClassName, style: { ...defaultMenuStyle, ...menuStyle }, children: items.map((item, index) => /* @__PURE__ */ jsxs26("div", { children: [
|
|
1724
|
-
index > 0 && item.danger ? /* @__PURE__ */ jsx38("div", { style: { borderTop: "1px solid var(--color-border)" } }) : null,
|
|
1725
|
-
/* @__PURE__ */ jsxs26(
|
|
1726
|
-
"button",
|
|
1727
|
-
{
|
|
1728
|
-
type: "button",
|
|
1729
|
-
className: itemBaseClass,
|
|
1730
|
-
style: { color: item.danger ? "var(--color-warn)" : "var(--color-txt-2)" },
|
|
1731
|
-
disabled: item.disabled || item.loading,
|
|
1732
|
-
onClick: () => {
|
|
1733
|
-
setOpen(false);
|
|
1734
|
-
item.onSelect();
|
|
1735
|
-
},
|
|
1736
|
-
children: [
|
|
1737
|
-
item.loading ? /* @__PURE__ */ jsx38(Spinner, { color: "text-[var(--color-txt-3)]" }) : /* @__PURE__ */ jsx38("span", { className: item.danger ? "shrink-0 text-warn" : "shrink-0 text-primary-300", children: item.icon }),
|
|
1738
|
-
/* @__PURE__ */ jsx38("span", { children: item.label })
|
|
1739
|
-
]
|
|
1740
|
-
}
|
|
1741
|
-
)
|
|
1742
|
-
] }, item.key)) })
|
|
1743
|
-
] }) : null
|
|
1970
|
+
typeof document !== "undefined" ? createPortal4(menuNode, document.body) : null
|
|
1744
1971
|
] });
|
|
1745
1972
|
}
|
|
1746
1973
|
|
|
@@ -1749,29 +1976,29 @@ import { useMemo as useMemo2, useState as useState6 } from "react";
|
|
|
1749
1976
|
|
|
1750
1977
|
// src/components/table/DataTableRow.tsx
|
|
1751
1978
|
import { memo } from "react";
|
|
1752
|
-
import { jsx as
|
|
1979
|
+
import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
1753
1980
|
var ALIGN_CLASS = {
|
|
1754
1981
|
left: "text-left",
|
|
1755
1982
|
center: "text-center",
|
|
1756
1983
|
right: "text-right"
|
|
1757
1984
|
};
|
|
1758
|
-
function DataTableRowInner({ row, columns, onRowClick, rowActions }) {
|
|
1985
|
+
function DataTableRowInner({ row, columns, onRowClick, rowActions, densityCellClass = "px-3 py-2.5", striped = true }) {
|
|
1759
1986
|
const clickable = Boolean(onRowClick);
|
|
1760
|
-
return /* @__PURE__ */
|
|
1987
|
+
return /* @__PURE__ */ jsxs29(
|
|
1761
1988
|
"tr",
|
|
1762
1989
|
{
|
|
1763
1990
|
onClick: clickable ? () => onRowClick?.(row) : void 0,
|
|
1764
|
-
className: `border-b border-border transition-colors hover:bg-
|
|
1991
|
+
className: `border-b border-[var(--tapiz-border-subtle)] transition-colors hover:bg-[var(--tapiz-bg-surface-muted)] ${striped ? "even:bg-[color-mix(in_srgb,var(--tapiz-bg-surface-muted)_35%,var(--tapiz-bg-surface))]" : ""} ${clickable ? "cursor-pointer" : ""}`,
|
|
1765
1992
|
children: [
|
|
1766
|
-
columns.map((column) => /* @__PURE__ */
|
|
1993
|
+
columns.map((column) => /* @__PURE__ */ jsx42(
|
|
1767
1994
|
"td",
|
|
1768
1995
|
{
|
|
1769
|
-
className:
|
|
1996
|
+
className: `${densityCellClass} text-xs text-[var(--tapiz-text-secondary)] ${ALIGN_CLASS[column.align ?? "left"]} ${column.className ?? ""}`,
|
|
1770
1997
|
children: column.cell(row)
|
|
1771
1998
|
},
|
|
1772
1999
|
column.id
|
|
1773
2000
|
)),
|
|
1774
|
-
rowActions !== void 0 && /* @__PURE__ */
|
|
2001
|
+
rowActions !== void 0 && /* @__PURE__ */ jsx42("td", { className: `${densityCellClass} text-right`, children: rowActions(row) })
|
|
1775
2002
|
]
|
|
1776
2003
|
}
|
|
1777
2004
|
);
|
|
@@ -1779,7 +2006,7 @@ function DataTableRowInner({ row, columns, onRowClick, rowActions }) {
|
|
|
1779
2006
|
var DataTableRow = memo(DataTableRowInner);
|
|
1780
2007
|
|
|
1781
2008
|
// src/components/table/DataTable.tsx
|
|
1782
|
-
import { jsx as
|
|
2009
|
+
import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
1783
2010
|
var ALIGN_CLASS2 = {
|
|
1784
2011
|
left: "text-left",
|
|
1785
2012
|
center: "text-center",
|
|
@@ -1809,7 +2036,12 @@ function DataTable({
|
|
|
1809
2036
|
rowActions,
|
|
1810
2037
|
serverSort,
|
|
1811
2038
|
footer,
|
|
1812
|
-
mobileCard
|
|
2039
|
+
mobileCard,
|
|
2040
|
+
density = "comfortable",
|
|
2041
|
+
variant = "default",
|
|
2042
|
+
stickyHeader = false,
|
|
2043
|
+
striped = true,
|
|
2044
|
+
className = ""
|
|
1813
2045
|
}) {
|
|
1814
2046
|
const [sort, setSort] = useState6(null);
|
|
1815
2047
|
const sortedData = useMemo2(() => {
|
|
@@ -1834,24 +2066,32 @@ function DataTable({
|
|
|
1834
2066
|
const hasActions = rowActions !== void 0;
|
|
1835
2067
|
const colCount = columns.length + (hasActions ? 1 : 0);
|
|
1836
2068
|
const tableClass = mobileCard !== void 0 ? "hidden md:table w-full text-sm table-collapse" : "w-full text-sm table-collapse";
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
2069
|
+
const densityHeaderClass = density === "compact" ? "px-3 py-2" : density === "spacious" ? "px-4 py-4" : "px-3 py-2.5";
|
|
2070
|
+
const densityCellClass = density === "compact" ? "px-3 py-2" : density === "spacious" ? "px-4 py-4" : "px-3 py-2.5";
|
|
2071
|
+
const wrapperClass = [
|
|
2072
|
+
"overflow-x-auto",
|
|
2073
|
+
variant === "brutal" ? "border-2 border-[var(--tapiz-border-strong)] shadow-[var(--tapiz-shadow-brutal)]" : "border border-[var(--tapiz-border-subtle)]",
|
|
2074
|
+
variant === "enterprise" ? "bg-[var(--tapiz-bg-surface)] shadow-[var(--tapiz-shadow-md)]" : "",
|
|
2075
|
+
className
|
|
2076
|
+
].filter(Boolean).join(" ");
|
|
2077
|
+
return /* @__PURE__ */ jsxs30("div", { className: wrapperClass, children: [
|
|
2078
|
+
mobileCard !== void 0 && /* @__PURE__ */ jsx43("div", { className: "md:hidden", children: isLoading ? Array.from({ length: loadingRows }).map((_, i) => /* @__PURE__ */ jsx43("div", { className: "h-16 animate-pulse bg-ink-300" }, i)) : sortedData.length === 0 ? emptyState : sortedData.map((row) => /* @__PURE__ */ jsx43("div", { children: mobileCard(row) }, rowKey(row))) }),
|
|
2079
|
+
/* @__PURE__ */ jsxs30("table", { className: tableClass, children: [
|
|
2080
|
+
/* @__PURE__ */ jsx43("thead", { children: /* @__PURE__ */ jsxs30("tr", { className: "border-b border-border bg-ink-300", children: [
|
|
1841
2081
|
columns.map((column) => {
|
|
1842
|
-
const baseClass =
|
|
2082
|
+
const baseClass = `${densityHeaderClass} ${stickyHeader ? "sticky top-0 z-10" : ""} ${ALIGN_CLASS2[column.align ?? "left"]} font-mono text-[11px] tracking-[.08em] text-txt-4 font-semibold whitespace-nowrap`;
|
|
1843
2083
|
if (!column.sortable || !column.sortAccessor) {
|
|
1844
|
-
return /* @__PURE__ */
|
|
2084
|
+
return /* @__PURE__ */ jsx43("th", { scope: "col", className: baseClass, children: column.header }, column.id);
|
|
1845
2085
|
}
|
|
1846
2086
|
const active = serverSort ? serverSort.field === column.id : sort?.columnId === column.id;
|
|
1847
2087
|
const direction = serverSort ? serverSort.dir : sort?.direction ?? "asc";
|
|
1848
|
-
return /* @__PURE__ */
|
|
2088
|
+
return /* @__PURE__ */ jsx43(
|
|
1849
2089
|
"th",
|
|
1850
2090
|
{
|
|
1851
2091
|
scope: "col",
|
|
1852
2092
|
"aria-sort": ariaSort(active, direction),
|
|
1853
2093
|
className: baseClass,
|
|
1854
|
-
children: /* @__PURE__ */
|
|
2094
|
+
children: /* @__PURE__ */ jsxs30(
|
|
1855
2095
|
"button",
|
|
1856
2096
|
{
|
|
1857
2097
|
type: "button",
|
|
@@ -1859,7 +2099,7 @@ function DataTable({
|
|
|
1859
2099
|
className: `inline-flex items-center gap-1 select-none transition-colors hover:text-txt-1 ${active ? "text-txt-1" : ""}`,
|
|
1860
2100
|
children: [
|
|
1861
2101
|
column.header,
|
|
1862
|
-
active && (direction === "asc" ? /* @__PURE__ */
|
|
2102
|
+
active && (direction === "asc" ? /* @__PURE__ */ jsx43(ChevronUp, { size: 12 }) : /* @__PURE__ */ jsx43(ChevronDown, { size: 12 }))
|
|
1863
2103
|
]
|
|
1864
2104
|
}
|
|
1865
2105
|
)
|
|
@@ -1867,15 +2107,17 @@ function DataTable({
|
|
|
1867
2107
|
column.id
|
|
1868
2108
|
);
|
|
1869
2109
|
}),
|
|
1870
|
-
hasActions && /* @__PURE__ */
|
|
2110
|
+
hasActions && /* @__PURE__ */ jsx43("th", { scope: "col", className: "px-3 py-2.5 text-right font-mono text-[11px] tracking-[.08em] text-txt-4 font-semibold whitespace-nowrap" })
|
|
1871
2111
|
] }) }),
|
|
1872
|
-
/* @__PURE__ */
|
|
2112
|
+
/* @__PURE__ */ jsx43("tbody", { children: isLoading ? Array.from({ length: loadingRows }).map((_, rowIndex) => /* @__PURE__ */ jsx43("tr", { className: "border-b border-[var(--tapiz-border-subtle)]", children: Array.from({ length: colCount }).map((__, colIndex) => /* @__PURE__ */ jsx43("td", { className: densityCellClass, children: /* @__PURE__ */ jsx43("div", { className: "h-4 w-24 animate-pulse bg-[var(--tapiz-bg-surface-muted)]" }) }, colIndex)) }, rowIndex)) : sortedData.length === 0 ? /* @__PURE__ */ jsx43("tr", { children: /* @__PURE__ */ jsx43("td", { colSpan: colCount, className: "px-4 py-10 text-center text-txt-4 text-sm font-mono", children: emptyState }) }) : sortedData.map((row) => /* @__PURE__ */ jsx43(
|
|
1873
2113
|
DataTableRow,
|
|
1874
2114
|
{
|
|
1875
2115
|
row,
|
|
1876
2116
|
columns,
|
|
1877
2117
|
onRowClick,
|
|
1878
|
-
rowActions
|
|
2118
|
+
rowActions,
|
|
2119
|
+
densityCellClass,
|
|
2120
|
+
striped
|
|
1879
2121
|
},
|
|
1880
2122
|
rowKey(row)
|
|
1881
2123
|
)) })
|
|
@@ -1883,24 +2125,1688 @@ function DataTable({
|
|
|
1883
2125
|
footer !== void 0 && footer
|
|
1884
2126
|
] });
|
|
1885
2127
|
}
|
|
2128
|
+
|
|
2129
|
+
// src/components/marketing/MarketingShell.tsx
|
|
2130
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
2131
|
+
function MarketingShell({ children, className = "", grid = true, noise = true }) {
|
|
2132
|
+
return /* @__PURE__ */ jsx44(
|
|
2133
|
+
"main",
|
|
2134
|
+
{
|
|
2135
|
+
className: [
|
|
2136
|
+
"min-h-screen overflow-hidden bg-[var(--tapiz-bg-page)] text-[var(--tapiz-text-primary)]",
|
|
2137
|
+
grid ? "tapiz-grid-bg" : "",
|
|
2138
|
+
noise ? "tapiz-noise-bg" : "",
|
|
2139
|
+
className
|
|
2140
|
+
].filter(Boolean).join(" "),
|
|
2141
|
+
children
|
|
2142
|
+
}
|
|
2143
|
+
);
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
// src/components/marketing/HeroFrame.tsx
|
|
2147
|
+
import { jsx as jsx45, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2148
|
+
function HeroFrame({ eyebrow, title, description, actions, visual, meta, className = "" }) {
|
|
2149
|
+
return /* @__PURE__ */ jsxs31("section", { className: `mx-auto grid max-w-7xl gap-10 px-[var(--tapiz-space-page-x)] py-[var(--tapiz-space-section-y)] lg:grid-cols-[1fr_0.9fr] lg:items-center ${className}`, children: [
|
|
2150
|
+
/* @__PURE__ */ jsxs31("div", { className: "animate-fade-in-up", children: [
|
|
2151
|
+
eyebrow ? /* @__PURE__ */ jsx45("div", { className: "kicker mb-4", children: eyebrow }) : null,
|
|
2152
|
+
/* @__PURE__ */ jsx45("h1", { className: "max-w-4xl text-5xl font-semibold leading-[0.95] tracking-[-0.07em] text-[var(--tapiz-text-primary)] md:text-7xl", children: title }),
|
|
2153
|
+
description ? /* @__PURE__ */ jsx45("p", { className: "mt-6 max-w-2xl text-base leading-7 text-[var(--tapiz-text-secondary)] md:text-lg", children: description }) : null,
|
|
2154
|
+
actions ? /* @__PURE__ */ jsx45("div", { className: "mt-8 flex flex-wrap gap-3", children: actions }) : null,
|
|
2155
|
+
meta ? /* @__PURE__ */ jsx45("div", { className: "mt-8 border-l-2 border-[var(--tapiz-accent)] pl-4 font-mono text-xs text-[var(--tapiz-text-muted)]", children: meta }) : null
|
|
2156
|
+
] }),
|
|
2157
|
+
visual ? /* @__PURE__ */ jsx45("div", { className: "animate-scale-in border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] p-3 shadow-[var(--tapiz-shadow-brutal-lg)]", children: visual }) : null
|
|
2158
|
+
] });
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
// src/components/marketing/FeatureCard.tsx
|
|
2162
|
+
import { jsx as jsx46, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2163
|
+
function FeatureCard({ title, description, icon, eyebrow, children, className = "", variant = "surface" }) {
|
|
2164
|
+
return /* @__PURE__ */ jsxs32(Card, { variant, hover: true, className: `group ${className}`, children: [
|
|
2165
|
+
/* @__PURE__ */ jsxs32("div", { className: "flex items-start gap-4", children: [
|
|
2166
|
+
icon ? /* @__PURE__ */ jsx46("div", { className: "grid h-11 w-11 shrink-0 place-items-center border border-[var(--tapiz-border-strong)] bg-[var(--color-icon-bg)] text-[var(--tapiz-accent)] group-hover:translate-x-[-1px] group-hover:translate-y-[-1px]", children: icon }) : null,
|
|
2167
|
+
/* @__PURE__ */ jsxs32("div", { className: "min-w-0", children: [
|
|
2168
|
+
eyebrow ? /* @__PURE__ */ jsx46("div", { className: "kicker mb-1", children: eyebrow }) : null,
|
|
2169
|
+
/* @__PURE__ */ jsx46("h3", { className: "text-lg font-semibold text-[var(--tapiz-text-primary)]", children: title }),
|
|
2170
|
+
description ? /* @__PURE__ */ jsx46("p", { className: "mt-2 text-sm leading-6 text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
2171
|
+
] })
|
|
2172
|
+
] }),
|
|
2173
|
+
children ? /* @__PURE__ */ jsx46("div", { className: "mt-5", children }) : null
|
|
2174
|
+
] });
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
// src/components/marketing/FeatureGrid.tsx
|
|
2178
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
2179
|
+
function FeatureGrid({ children, className = "" }) {
|
|
2180
|
+
return /* @__PURE__ */ jsx47("div", { className: `grid gap-4 md:grid-cols-2 xl:grid-cols-3 ${className}`, children });
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
// src/components/marketing/CTASection.tsx
|
|
2184
|
+
import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2185
|
+
function CTASection({ eyebrow, title, description, actions, className = "" }) {
|
|
2186
|
+
return /* @__PURE__ */ jsx48("section", { className: `mx-auto max-w-7xl px-[var(--tapiz-space-page-x)] py-[var(--tapiz-space-section-y)] ${className}`, children: /* @__PURE__ */ jsxs33("div", { className: "border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] p-8 shadow-[var(--tapiz-shadow-brutal-lg)] md:p-12", children: [
|
|
2187
|
+
eyebrow ? /* @__PURE__ */ jsx48("div", { className: "kicker mb-3", children: eyebrow }) : null,
|
|
2188
|
+
/* @__PURE__ */ jsxs33("div", { className: "grid gap-6 lg:grid-cols-[1fr_auto] lg:items-end", children: [
|
|
2189
|
+
/* @__PURE__ */ jsxs33("div", { children: [
|
|
2190
|
+
/* @__PURE__ */ jsx48("h2", { className: "max-w-3xl text-3xl font-semibold tracking-[-0.05em] md:text-5xl", children: title }),
|
|
2191
|
+
description ? /* @__PURE__ */ jsx48("p", { className: "mt-4 max-w-2xl text-base leading-7 text-[var(--tapiz-text-secondary)]", children: description }) : null
|
|
2192
|
+
] }),
|
|
2193
|
+
actions ? /* @__PURE__ */ jsx48("div", { className: "flex flex-wrap gap-3", children: actions }) : null
|
|
2194
|
+
] })
|
|
2195
|
+
] }) });
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
// src/components/marketing/MockupFrame.tsx
|
|
2199
|
+
import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2200
|
+
function MockupFrame({ children, title, toolbar, className = "" }) {
|
|
2201
|
+
return /* @__PURE__ */ jsxs34("div", { className: `overflow-hidden border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] shadow-[var(--tapiz-shadow-brutal)] ${className}`, children: [
|
|
2202
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between border-b border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)] px-3 py-2", children: [
|
|
2203
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-1.5", children: [
|
|
2204
|
+
/* @__PURE__ */ jsx49("span", { className: "h-2.5 w-2.5 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-danger)]" }),
|
|
2205
|
+
/* @__PURE__ */ jsx49("span", { className: "h-2.5 w-2.5 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-warning)]" }),
|
|
2206
|
+
/* @__PURE__ */ jsx49("span", { className: "h-2.5 w-2.5 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-success)]" })
|
|
2207
|
+
] }),
|
|
2208
|
+
title ? /* @__PURE__ */ jsx49("div", { className: "font-mono text-[10px] uppercase tracking-widest text-[var(--tapiz-text-muted)]", children: title }) : null,
|
|
2209
|
+
/* @__PURE__ */ jsx49("div", { children: toolbar })
|
|
2210
|
+
] }),
|
|
2211
|
+
/* @__PURE__ */ jsx49("div", { className: "p-4", children })
|
|
2212
|
+
] });
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
// src/components/marketing/ComparisonTable.tsx
|
|
2216
|
+
import { jsx as jsx50, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2217
|
+
function ComparisonTable({ rows, featureHeader = "Feature", includedHeader = "Tapiz", alternativeHeader = "Other", className = "" }) {
|
|
2218
|
+
return /* @__PURE__ */ jsx50("div", { className: `overflow-x-auto border border-[var(--tapiz-border-strong)] ${className}`, children: /* @__PURE__ */ jsxs35("table", { className: "w-full text-sm", children: [
|
|
2219
|
+
/* @__PURE__ */ jsx50("thead", { children: /* @__PURE__ */ jsxs35("tr", { children: [
|
|
2220
|
+
/* @__PURE__ */ jsx50("th", { className: "px-4 py-3 text-left", children: featureHeader }),
|
|
2221
|
+
/* @__PURE__ */ jsx50("th", { className: "px-4 py-3 text-left", children: includedHeader }),
|
|
2222
|
+
/* @__PURE__ */ jsx50("th", { className: "px-4 py-3 text-left", children: alternativeHeader })
|
|
2223
|
+
] }) }),
|
|
2224
|
+
/* @__PURE__ */ jsx50("tbody", { children: rows.map((row, index) => /* @__PURE__ */ jsxs35("tr", { className: "border-t border-[var(--tapiz-border-subtle)]", children: [
|
|
2225
|
+
/* @__PURE__ */ jsx50("td", { className: "px-4 py-3 font-medium text-[var(--tapiz-text-primary)]", children: row.feature }),
|
|
2226
|
+
/* @__PURE__ */ jsx50("td", { className: "px-4 py-3 text-[var(--tapiz-text-secondary)]", children: row.included }),
|
|
2227
|
+
/* @__PURE__ */ jsx50("td", { className: "px-4 py-3 text-[var(--tapiz-text-muted)]", children: row.alternative })
|
|
2228
|
+
] }, index)) })
|
|
2229
|
+
] }) });
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
// src/components/layout/AppShell.tsx
|
|
2233
|
+
import { jsx as jsx51, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2234
|
+
var variantClasses4 = {
|
|
2235
|
+
default: "bg-[var(--tapiz-bg-page)]",
|
|
2236
|
+
grid: "bg-[var(--tapiz-bg-page)] tapiz-grid-bg",
|
|
2237
|
+
noise: "bg-[var(--tapiz-bg-page)] tapiz-noise-bg"
|
|
2238
|
+
};
|
|
2239
|
+
function AppShell({ sidebar, topbar, children, aside, className = "", contentClassName = "", variant = "default" }) {
|
|
2240
|
+
return /* @__PURE__ */ jsxs36("div", { className: `min-h-screen text-[var(--tapiz-text-primary)] ${variantClasses4[variant]} ${className}`, children: [
|
|
2241
|
+
topbar,
|
|
2242
|
+
/* @__PURE__ */ jsxs36("div", { className: "mx-auto flex w-full max-w-[1600px]", children: [
|
|
2243
|
+
sidebar ? /* @__PURE__ */ jsx51("aside", { className: "hidden min-h-[calc(100vh-1px)] w-72 shrink-0 border-r border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] lg:block", children: sidebar }) : null,
|
|
2244
|
+
/* @__PURE__ */ jsx51("main", { className: `min-w-0 flex-1 px-[var(--tapiz-space-page-x)] py-6 ${contentClassName}`, children }),
|
|
2245
|
+
aside ? /* @__PURE__ */ jsx51("aside", { className: "hidden w-80 shrink-0 border-l border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] xl:block", children: aside }) : null
|
|
2246
|
+
] })
|
|
2247
|
+
] });
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
// src/components/layout/SplitPane.tsx
|
|
2251
|
+
import { jsx as jsx52, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2252
|
+
var ratios = {
|
|
2253
|
+
"50/50": "lg:grid-cols-2",
|
|
2254
|
+
"60/40": "lg:grid-cols-[minmax(0,3fr)_minmax(320px,2fr)]",
|
|
2255
|
+
"70/30": "lg:grid-cols-[minmax(0,7fr)_minmax(280px,3fr)]"
|
|
2256
|
+
};
|
|
2257
|
+
function SplitPane({ primary, secondary, ratio = "60/40", reverseOnMobile = false, className = "" }) {
|
|
2258
|
+
return /* @__PURE__ */ jsxs37("div", { className: `grid gap-5 ${ratios[ratio]} ${className}`, children: [
|
|
2259
|
+
/* @__PURE__ */ jsx52("div", { className: reverseOnMobile ? "order-2 lg:order-1" : "", children: primary }),
|
|
2260
|
+
/* @__PURE__ */ jsx52("div", { className: reverseOnMobile ? "order-1 lg:order-2" : "", children: secondary })
|
|
2261
|
+
] });
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
// src/components/layout/Stack.tsx
|
|
2265
|
+
import { jsx as jsx53 } from "react/jsx-runtime";
|
|
2266
|
+
var gapClasses = { xs: "gap-1", sm: "gap-2", md: "gap-4", lg: "gap-6", xl: "gap-8" };
|
|
2267
|
+
var alignClasses = { start: "items-start", center: "items-center", end: "items-end", stretch: "items-stretch" };
|
|
2268
|
+
var justifyClasses = { start: "justify-start", center: "justify-center", between: "justify-between", end: "justify-end" };
|
|
2269
|
+
function Stack({ children, gap = "md", direction = "vertical", align = "stretch", justify = "start", wrap = false, className = "" }) {
|
|
2270
|
+
return /* @__PURE__ */ jsx53("div", { className: `flex ${direction === "vertical" ? "flex-col" : "flex-row"} ${gapClasses[gap]} ${alignClasses[align]} ${justifyClasses[justify]} ${wrap ? "flex-wrap" : ""} ${className}`, children });
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
// src/components/layout/Cluster.tsx
|
|
2274
|
+
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
2275
|
+
var gapClasses2 = { xs: "gap-1", sm: "gap-2", md: "gap-3", lg: "gap-5" };
|
|
2276
|
+
var alignClasses2 = { start: "items-start", center: "items-center", end: "items-end" };
|
|
2277
|
+
var justifyClasses2 = { start: "justify-start", center: "justify-center", between: "justify-between", end: "justify-end" };
|
|
2278
|
+
function Cluster({ children, gap = "sm", align = "center", justify = "start", className = "" }) {
|
|
2279
|
+
return /* @__PURE__ */ jsx54("div", { className: `flex flex-wrap ${gapClasses2[gap]} ${alignClasses2[align]} ${justifyClasses2[justify]} ${className}`, children });
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
// src/components/navigation/Breadcrumbs.tsx
|
|
2283
|
+
import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
2284
|
+
function Breadcrumbs({ items, separator = "/", className = "" }) {
|
|
2285
|
+
return /* @__PURE__ */ jsx55("nav", { "aria-label": "Breadcrumb", className: `font-mono text-[10px] uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)] ${className}`, children: /* @__PURE__ */ jsx55("ol", { className: "flex flex-wrap items-center gap-2", children: items.map((item, index) => /* @__PURE__ */ jsxs38("li", { className: "flex items-center gap-2", children: [
|
|
2286
|
+
index > 0 ? /* @__PURE__ */ jsx55("span", { "aria-hidden": "true", className: "text-[var(--tapiz-text-disabled)]", children: separator }) : null,
|
|
2287
|
+
item.href && !item.current ? /* @__PURE__ */ jsx55("a", { className: "hover:text-[var(--tapiz-accent)]", href: item.href, children: item.label }) : /* @__PURE__ */ jsx55("span", { "aria-current": item.current ? "page" : void 0, className: item.current ? "text-[var(--tapiz-text-primary)]" : "", children: item.label })
|
|
2288
|
+
] }, index)) }) });
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
// src/components/navigation/SidebarNav.tsx
|
|
2292
|
+
import { Fragment as Fragment2, jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
2293
|
+
function SidebarNav({ groups, header, footer, className = "" }) {
|
|
2294
|
+
return /* @__PURE__ */ jsxs39("div", { className: `flex h-full min-h-screen flex-col bg-[var(--tapiz-bg-surface)] ${className}`, children: [
|
|
2295
|
+
header ? /* @__PURE__ */ jsx56("div", { className: "border-b border-[var(--tapiz-border-subtle)] p-4", children: header }) : null,
|
|
2296
|
+
/* @__PURE__ */ jsx56("nav", { className: "flex-1 space-y-6 p-3", children: groups.map((group, groupIndex) => /* @__PURE__ */ jsxs39("div", { children: [
|
|
2297
|
+
group.label ? /* @__PURE__ */ jsx56("div", { className: "mb-2 px-2 font-mono text-[10px] font-bold uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: group.label }) : null,
|
|
2298
|
+
/* @__PURE__ */ jsx56("div", { className: "space-y-1", children: group.items.map((item, itemIndex) => /* @__PURE__ */ jsx56(SidebarNavLink, { item }, itemIndex)) })
|
|
2299
|
+
] }, groupIndex)) }),
|
|
2300
|
+
footer ? /* @__PURE__ */ jsx56("div", { className: "border-t border-[var(--tapiz-border-subtle)] p-4", children: footer }) : null
|
|
2301
|
+
] });
|
|
2302
|
+
}
|
|
2303
|
+
function SidebarNavLink({ item }) {
|
|
2304
|
+
const className = [
|
|
2305
|
+
"flex w-full items-center gap-3 border px-3 py-2 text-left text-sm font-medium",
|
|
2306
|
+
item.active ? "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)] text-[var(--tapiz-text-primary)] shadow-[inset_3px_0_0_var(--tapiz-accent)]" : "border-transparent text-[var(--tapiz-text-secondary)] hover:border-[var(--tapiz-border-subtle)] hover:bg-[var(--tapiz-bg-surface-muted)] hover:text-[var(--tapiz-text-primary)]",
|
|
2307
|
+
item.disabled ? "pointer-events-none opacity-40" : ""
|
|
2308
|
+
].filter(Boolean).join(" ");
|
|
2309
|
+
const content = /* @__PURE__ */ jsxs39(Fragment2, { children: [
|
|
2310
|
+
item.icon ? /* @__PURE__ */ jsx56("span", { className: "grid size-5 place-items-center text-[var(--tapiz-text-muted)]", children: item.icon }) : null,
|
|
2311
|
+
/* @__PURE__ */ jsx56("span", { className: "min-w-0 flex-1 truncate", children: item.label }),
|
|
2312
|
+
item.badge ? /* @__PURE__ */ jsx56("span", { children: item.badge }) : null
|
|
2313
|
+
] });
|
|
2314
|
+
return item.href ? /* @__PURE__ */ jsx56("a", { className, href: item.href, children: content }) : /* @__PURE__ */ jsx56("button", { type: "button", className, onClick: item.onClick, disabled: item.disabled, children: content });
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
// src/components/navigation/TopNav.tsx
|
|
2318
|
+
import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
2319
|
+
function TopNav({ brand, links = [], actions, className = "", sticky = true }) {
|
|
2320
|
+
return /* @__PURE__ */ jsx57("header", { className: `${sticky ? "sticky top-0 z-40" : ""} border-b border-[var(--tapiz-border-subtle)] bg-[color-mix(in_srgb,var(--tapiz-bg-surface)_88%,transparent)] backdrop-blur-xl ${className}`, children: /* @__PURE__ */ jsxs40("div", { className: "mx-auto flex h-16 max-w-[1600px] items-center gap-6 px-[var(--tapiz-space-page-x)]", children: [
|
|
2321
|
+
brand ? /* @__PURE__ */ jsx57("div", { className: "shrink-0", children: brand }) : null,
|
|
2322
|
+
/* @__PURE__ */ jsx57("nav", { className: "hidden items-center gap-1 md:flex", children: links.map((link, index) => {
|
|
2323
|
+
const cls = `border px-3 py-1.5 text-sm font-medium ${link.active ? "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)] text-[var(--tapiz-text-primary)]" : "border-transparent text-[var(--tapiz-text-secondary)] hover:border-[var(--tapiz-border-subtle)] hover:text-[var(--tapiz-text-primary)]"}`;
|
|
2324
|
+
return link.href ? /* @__PURE__ */ jsx57("a", { href: link.href, className: cls, children: link.label }, index) : /* @__PURE__ */ jsx57("button", { type: "button", onClick: link.onClick, className: cls, children: link.label }, index);
|
|
2325
|
+
}) }),
|
|
2326
|
+
actions ? /* @__PURE__ */ jsx57("div", { className: "ml-auto flex items-center gap-2", children: actions }) : null
|
|
2327
|
+
] }) });
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
// src/components/disclosure/Tabs.tsx
|
|
2331
|
+
import { jsx as jsx58, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
2332
|
+
var variants = {
|
|
2333
|
+
line: "border-b border-[var(--tapiz-border-subtle)]",
|
|
2334
|
+
boxed: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)] p-1",
|
|
2335
|
+
brutal: "border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] p-1 shadow-[var(--tapiz-shadow-brutal)]"
|
|
2336
|
+
};
|
|
2337
|
+
function Tabs({ items, activeId, onChange, className = "", variant = "line" }) {
|
|
2338
|
+
const active = items.find((item) => item.id === activeId) ?? items[0];
|
|
2339
|
+
return /* @__PURE__ */ jsxs41("div", { className, children: [
|
|
2340
|
+
/* @__PURE__ */ jsx58("div", { role: "tablist", className: `flex flex-wrap gap-1 ${variants[variant]}`, children: items.map((item) => {
|
|
2341
|
+
const selected = item.id === active?.id;
|
|
2342
|
+
return /* @__PURE__ */ jsxs41(
|
|
2343
|
+
"button",
|
|
2344
|
+
{
|
|
2345
|
+
type: "button",
|
|
2346
|
+
role: "tab",
|
|
2347
|
+
"aria-selected": selected,
|
|
2348
|
+
disabled: item.disabled,
|
|
2349
|
+
onClick: () => onChange?.(item.id),
|
|
2350
|
+
className: `inline-flex items-center gap-2 px-3 py-2 text-sm font-semibold disabled:cursor-not-allowed disabled:opacity-40 ${selected ? "bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-primary)] shadow-[inset_0_-2px_0_var(--tapiz-accent)]" : "text-[var(--tapiz-text-muted)] hover:bg-[var(--tapiz-bg-surface)] hover:text-[var(--tapiz-text-primary)]"}`,
|
|
2351
|
+
children: [
|
|
2352
|
+
item.label,
|
|
2353
|
+
item.badge
|
|
2354
|
+
]
|
|
2355
|
+
},
|
|
2356
|
+
item.id
|
|
2357
|
+
);
|
|
2358
|
+
}) }),
|
|
2359
|
+
/* @__PURE__ */ jsx58("div", { role: "tabpanel", className: "pt-4", children: active?.content })
|
|
2360
|
+
] });
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
// src/components/disclosure/Accordion.tsx
|
|
2364
|
+
import { jsx as jsx59, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
2365
|
+
function Accordion({ items, openIds = [], onToggle, className = "" }) {
|
|
2366
|
+
return /* @__PURE__ */ jsx59("div", { className: `divide-y divide-[var(--tapiz-border-subtle)] border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] ${className}`, children: items.map((item) => {
|
|
2367
|
+
const open = openIds.includes(item.id);
|
|
2368
|
+
return /* @__PURE__ */ jsxs42("section", { children: [
|
|
2369
|
+
/* @__PURE__ */ jsxs42(
|
|
2370
|
+
"button",
|
|
2371
|
+
{
|
|
2372
|
+
type: "button",
|
|
2373
|
+
disabled: item.disabled,
|
|
2374
|
+
"aria-expanded": open,
|
|
2375
|
+
onClick: () => onToggle?.(item.id),
|
|
2376
|
+
className: "flex w-full items-center justify-between gap-4 px-4 py-3 text-left disabled:opacity-40",
|
|
2377
|
+
children: [
|
|
2378
|
+
/* @__PURE__ */ jsx59("span", { className: "font-semibold text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
2379
|
+
/* @__PURE__ */ jsxs42("span", { className: "flex items-center gap-3 text-[var(--tapiz-text-muted)]", children: [
|
|
2380
|
+
item.meta,
|
|
2381
|
+
/* @__PURE__ */ jsx59("span", { "aria-hidden": "true", className: "font-mono text-lg", children: open ? "\u2212" : "+" })
|
|
2382
|
+
] })
|
|
2383
|
+
]
|
|
2384
|
+
}
|
|
2385
|
+
),
|
|
2386
|
+
open ? /* @__PURE__ */ jsx59("div", { className: "border-t border-[var(--tapiz-border-subtle)] px-4 py-4 text-sm text-[var(--tapiz-text-secondary)]", children: item.content }) : null
|
|
2387
|
+
] }, item.id);
|
|
2388
|
+
}) });
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
// src/components/disclosure/Stepper.tsx
|
|
2392
|
+
import { jsx as jsx60, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
2393
|
+
var tone = {
|
|
2394
|
+
complete: "border-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)] text-[var(--tapiz-success)]",
|
|
2395
|
+
current: "border-[var(--tapiz-accent)] bg-[var(--tapiz-accent-soft)] text-[var(--tapiz-accent)]",
|
|
2396
|
+
upcoming: "border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-muted)]",
|
|
2397
|
+
error: "border-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)] text-[var(--tapiz-danger)]"
|
|
2398
|
+
};
|
|
2399
|
+
function Stepper({ steps, orientation = "horizontal", className = "" }) {
|
|
2400
|
+
return /* @__PURE__ */ jsx60("ol", { className: `grid gap-3 ${orientation === "horizontal" ? "md:grid-cols-[repeat(auto-fit,minmax(0,1fr))]" : ""} ${className}`, children: steps.map((step, index) => {
|
|
2401
|
+
const status = step.status ?? "upcoming";
|
|
2402
|
+
return /* @__PURE__ */ jsxs43("li", { className: "flex gap-3", children: [
|
|
2403
|
+
/* @__PURE__ */ jsx60("span", { className: `grid size-8 shrink-0 place-items-center border font-mono text-xs font-bold ${tone[status]}`, children: status === "complete" ? "\u2713" : index + 1 }),
|
|
2404
|
+
/* @__PURE__ */ jsxs43("span", { className: "min-w-0", children: [
|
|
2405
|
+
/* @__PURE__ */ jsx60("span", { className: "block text-sm font-semibold text-[var(--tapiz-text-primary)]", children: step.label }),
|
|
2406
|
+
step.description ? /* @__PURE__ */ jsx60("span", { className: "mt-1 block text-xs text-[var(--tapiz-text-muted)]", children: step.description }) : null
|
|
2407
|
+
] })
|
|
2408
|
+
] }, step.id);
|
|
2409
|
+
}) });
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
// src/components/overlays/Drawer.tsx
|
|
2413
|
+
import { jsx as jsx61, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
2414
|
+
function Drawer({ open, onClose, title, description, children, footer, side = "right", className = "" }) {
|
|
2415
|
+
if (!open) return null;
|
|
2416
|
+
return /* @__PURE__ */ jsxs44("div", { className: "fixed inset-0 z-50", children: [
|
|
2417
|
+
/* @__PURE__ */ jsx61("button", { type: "button", "aria-label": "Close drawer", className: "absolute inset-0 bg-[var(--tapiz-bg-overlay)]", onClick: onClose }),
|
|
2418
|
+
/* @__PURE__ */ jsxs44("section", { className: `absolute top-0 h-full w-full max-w-md border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] shadow-[var(--tapiz-shadow-lg)] ${side === "right" ? "right-0 border-l" : "left-0 border-r"} ${className}`, children: [
|
|
2419
|
+
/* @__PURE__ */ jsxs44("header", { className: "flex items-start justify-between gap-4 border-b border-[var(--tapiz-border-subtle)] p-5", children: [
|
|
2420
|
+
/* @__PURE__ */ jsxs44("div", { children: [
|
|
2421
|
+
title ? /* @__PURE__ */ jsx61("h2", { className: "text-lg font-semibold text-[var(--tapiz-text-primary)]", children: title }) : null,
|
|
2422
|
+
description ? /* @__PURE__ */ jsx61("p", { className: "mt-1 text-sm text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
2423
|
+
] }),
|
|
2424
|
+
/* @__PURE__ */ jsx61("button", { type: "button", onClick: onClose, className: "border border-[var(--tapiz-border-subtle)] px-2 py-1 font-mono text-sm text-[var(--tapiz-text-muted)] hover:text-[var(--tapiz-text-primary)]", children: "\xD7" })
|
|
2425
|
+
] }),
|
|
2426
|
+
/* @__PURE__ */ jsx61("div", { className: "max-h-[calc(100vh-9rem)] overflow-auto p-5", children }),
|
|
2427
|
+
footer ? /* @__PURE__ */ jsx61("footer", { className: "border-t border-[var(--tapiz-border-subtle)] p-4", children: footer }) : null
|
|
2428
|
+
] })
|
|
2429
|
+
] });
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
// src/components/overlays/Popover.tsx
|
|
2433
|
+
import { jsx as jsx62, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
2434
|
+
function Popover({ trigger, children, open = false, align = "start", className = "" }) {
|
|
2435
|
+
return /* @__PURE__ */ jsxs45("div", { className: `relative inline-block ${className}`, children: [
|
|
2436
|
+
trigger,
|
|
2437
|
+
open ? /* @__PURE__ */ jsx62("div", { className: `absolute top-full z-40 mt-2 min-w-64 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] p-2 shadow-[var(--tapiz-shadow-md)] ${align === "end" ? "right-0" : "left-0"}`, children }) : null
|
|
2438
|
+
] });
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
// src/components/overlays/CommandMenu.tsx
|
|
2442
|
+
import { jsx as jsx63, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
2443
|
+
function CommandMenu({ open, onClose, query = "", onQueryChange, groups, placeholder = "Search commands\u2026", empty = "No commands found." }) {
|
|
2444
|
+
if (!open) return null;
|
|
2445
|
+
const hasItems = groups.some((group) => group.items.length > 0);
|
|
2446
|
+
return /* @__PURE__ */ jsx63("div", { className: "fixed inset-0 z-50 grid place-items-start bg-[var(--tapiz-bg-overlay)] px-4 pt-[12vh]", onClick: onClose, children: /* @__PURE__ */ jsxs46("div", { className: "mx-auto w-full max-w-2xl border-2 border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] shadow-[var(--tapiz-shadow-brutal-lg)]", onClick: (e) => e.stopPropagation(), children: [
|
|
2447
|
+
/* @__PURE__ */ jsx63("div", { className: "border-b border-[var(--tapiz-border-subtle)] p-3", children: /* @__PURE__ */ jsx63(SearchInput, { value: query, onChange: (value) => onQueryChange?.(value), placeholder, autoFocus: true }) }),
|
|
2448
|
+
/* @__PURE__ */ jsxs46("div", { className: "max-h-[50vh] overflow-auto p-2", children: [
|
|
2449
|
+
!hasItems ? /* @__PURE__ */ jsx63("div", { className: "p-6 text-center text-sm text-[var(--tapiz-text-muted)]", children: empty }) : null,
|
|
2450
|
+
groups.map((group, groupIndex) => /* @__PURE__ */ jsxs46("div", { className: "py-2", children: [
|
|
2451
|
+
group.label ? /* @__PURE__ */ jsx63("div", { className: "px-2 pb-2 font-mono text-[10px] font-bold uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: group.label }) : null,
|
|
2452
|
+
group.items.map((item) => /* @__PURE__ */ jsxs46("button", { type: "button", disabled: item.disabled, onClick: item.onSelect, className: "flex w-full items-center gap-3 border border-transparent px-3 py-2 text-left hover:border-[var(--tapiz-border-subtle)] hover:bg-[var(--tapiz-bg-surface-muted)] disabled:opacity-40", children: [
|
|
2453
|
+
item.icon ? /* @__PURE__ */ jsx63("span", { className: "grid size-8 place-items-center border border-[var(--tapiz-border-subtle)] text-[var(--tapiz-text-muted)]", children: item.icon }) : null,
|
|
2454
|
+
/* @__PURE__ */ jsxs46("span", { className: "min-w-0 flex-1", children: [
|
|
2455
|
+
/* @__PURE__ */ jsx63("span", { className: "block text-sm font-semibold text-[var(--tapiz-text-primary)]", children: item.label }),
|
|
2456
|
+
item.description ? /* @__PURE__ */ jsx63("span", { className: "block text-xs text-[var(--tapiz-text-muted)]", children: item.description }) : null
|
|
2457
|
+
] }),
|
|
2458
|
+
item.shortcut ? /* @__PURE__ */ jsx63("span", { className: "font-mono text-[10px] text-[var(--tapiz-text-muted)]", children: item.shortcut }) : null
|
|
2459
|
+
] }, item.id))
|
|
2460
|
+
] }, groupIndex))
|
|
2461
|
+
] })
|
|
2462
|
+
] }) });
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
// src/components/forms/FormField.tsx
|
|
2466
|
+
import { jsx as jsx64, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
2467
|
+
function FormField({ label, hint, error, required, htmlFor, children, className = "" }) {
|
|
2468
|
+
return /* @__PURE__ */ jsxs47("div", { className: `space-y-1.5 ${className}`, children: [
|
|
2469
|
+
label ? /* @__PURE__ */ jsxs47(FieldLabel, { htmlFor, children: [
|
|
2470
|
+
label,
|
|
2471
|
+
required ? " *" : ""
|
|
2472
|
+
] }) : null,
|
|
2473
|
+
children,
|
|
2474
|
+
error ? /* @__PURE__ */ jsx64(FormError, { message: String(error) }) : hint ? /* @__PURE__ */ jsx64(FieldHint, { children: hint }) : null
|
|
2475
|
+
] });
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
// src/components/forms/Switch.tsx
|
|
2479
|
+
import { jsx as jsx65, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
2480
|
+
function Switch({ checked = false, onChange, disabled, label, description, className = "" }) {
|
|
2481
|
+
return /* @__PURE__ */ jsxs48("label", { className: `flex cursor-pointer items-start gap-3 ${disabled ? "cursor-not-allowed opacity-50" : ""} ${className}`, children: [
|
|
2482
|
+
/* @__PURE__ */ jsx65(
|
|
2483
|
+
"button",
|
|
2484
|
+
{
|
|
2485
|
+
type: "button",
|
|
2486
|
+
role: "switch",
|
|
2487
|
+
"aria-checked": checked,
|
|
2488
|
+
disabled,
|
|
2489
|
+
onClick: () => onChange?.(!checked),
|
|
2490
|
+
className: `relative mt-0.5 h-6 w-11 border border-[var(--tapiz-border-strong)] ${checked ? "bg-[var(--tapiz-accent)]" : "bg-[var(--tapiz-bg-surface-muted)]"}`,
|
|
2491
|
+
children: /* @__PURE__ */ jsx65("span", { className: `absolute top-0.5 size-4 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] transition-transform ${checked ? "left-5" : "left-0.5"}` })
|
|
2492
|
+
}
|
|
2493
|
+
),
|
|
2494
|
+
label || description ? /* @__PURE__ */ jsxs48("span", { children: [
|
|
2495
|
+
label ? /* @__PURE__ */ jsx65("span", { className: "block text-sm font-semibold text-[var(--tapiz-text-primary)]", children: label }) : null,
|
|
2496
|
+
description ? /* @__PURE__ */ jsx65("span", { className: "block text-xs text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
2497
|
+
] }) : null
|
|
2498
|
+
] });
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
// src/components/forms/ToggleGroup.tsx
|
|
2502
|
+
import { jsx as jsx66 } from "react/jsx-runtime";
|
|
2503
|
+
function ToggleGroup({ options, value, onChange, className = "", fullWidth = false }) {
|
|
2504
|
+
return /* @__PURE__ */ jsx66("div", { className: `inline-flex border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)] p-1 ${fullWidth ? "w-full" : ""} ${className}`, children: options.map((option) => {
|
|
2505
|
+
const selected = option.value === value;
|
|
2506
|
+
return /* @__PURE__ */ jsx66(
|
|
2507
|
+
"button",
|
|
2508
|
+
{
|
|
2509
|
+
type: "button",
|
|
2510
|
+
disabled: option.disabled,
|
|
2511
|
+
onClick: () => onChange?.(option.value),
|
|
2512
|
+
className: `px-3 py-1.5 text-sm font-semibold disabled:opacity-40 ${fullWidth ? "flex-1" : ""} ${selected ? "bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-primary)] shadow-[inset_0_-2px_0_var(--tapiz-accent)]" : "text-[var(--tapiz-text-muted)] hover:text-[var(--tapiz-text-primary)]"}`,
|
|
2513
|
+
children: option.label
|
|
2514
|
+
},
|
|
2515
|
+
option.value
|
|
2516
|
+
);
|
|
2517
|
+
}) });
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
// src/components/forms/InputGroup.tsx
|
|
2521
|
+
import { jsx as jsx67, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
2522
|
+
function InputGroup({ prefix, suffix, children, className = "" }) {
|
|
2523
|
+
return /* @__PURE__ */ jsxs49("div", { className: `flex items-stretch border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] focus-within:border-[var(--tapiz-border-focus)] focus-within:shadow-[inset_3px_0_0_var(--tapiz-signal)] ${className}`, children: [
|
|
2524
|
+
prefix ? /* @__PURE__ */ jsx67("div", { className: "flex items-center border-r border-[var(--tapiz-border-subtle)] px-3 text-sm text-[var(--tapiz-text-muted)]", children: prefix }) : null,
|
|
2525
|
+
/* @__PURE__ */ jsx67("div", { className: "min-w-0 flex-1 [&_input]:border-0 [&_input]:shadow-none [&_input]:focus:shadow-none", children }),
|
|
2526
|
+
suffix ? /* @__PURE__ */ jsx67("div", { className: "flex items-center border-l border-[var(--tapiz-border-subtle)] px-3 text-sm text-[var(--tapiz-text-muted)]", children: suffix }) : null
|
|
2527
|
+
] });
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
// src/components/feedback/Alert.tsx
|
|
2531
|
+
import { jsx as jsx68, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
2532
|
+
var toneClasses = {
|
|
2533
|
+
info: "border-[var(--tapiz-info)] bg-[var(--tapiz-info-soft)] text-[var(--tapiz-info)]",
|
|
2534
|
+
success: "border-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)] text-[var(--tapiz-success)]",
|
|
2535
|
+
warning: "border-[var(--tapiz-warning)] bg-[var(--tapiz-warning-soft)] text-[var(--tapiz-warning)]",
|
|
2536
|
+
danger: "border-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)] text-[var(--tapiz-danger)]",
|
|
2537
|
+
neutral: "border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-secondary)]"
|
|
2538
|
+
};
|
|
2539
|
+
function Alert2({ tone: tone2 = "info", title, children, icon, actions, className = "" }) {
|
|
2540
|
+
return /* @__PURE__ */ jsxs50("div", { className: `flex gap-3 border p-4 ${toneClasses[tone2]} ${className}`, children: [
|
|
2541
|
+
icon ? /* @__PURE__ */ jsx68("div", { className: "mt-0.5 shrink-0", children: icon }) : null,
|
|
2542
|
+
/* @__PURE__ */ jsxs50("div", { className: "min-w-0 flex-1", children: [
|
|
2543
|
+
title ? /* @__PURE__ */ jsx68("div", { className: "font-semibold text-[var(--tapiz-text-primary)]", children: title }) : null,
|
|
2544
|
+
children ? /* @__PURE__ */ jsx68("div", { className: "mt-1 text-sm text-[var(--tapiz-text-secondary)]", children }) : null
|
|
2545
|
+
] }),
|
|
2546
|
+
actions ? /* @__PURE__ */ jsx68("div", { className: "shrink-0", children: actions }) : null
|
|
2547
|
+
] });
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// src/components/feedback/Progress.tsx
|
|
2551
|
+
import { jsx as jsx69, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
2552
|
+
var tones = {
|
|
2553
|
+
accent: "bg-[var(--tapiz-accent)]",
|
|
2554
|
+
success: "bg-[var(--tapiz-success)]",
|
|
2555
|
+
warning: "bg-[var(--tapiz-warning)]",
|
|
2556
|
+
danger: "bg-[var(--tapiz-danger)]"
|
|
2557
|
+
};
|
|
2558
|
+
function Progress({ value, max = 100, label, showValue = false, tone: tone2 = "accent", className = "" }) {
|
|
2559
|
+
const percentage = Math.max(0, Math.min(100, value / max * 100));
|
|
2560
|
+
return /* @__PURE__ */ jsxs51("div", { className, children: [
|
|
2561
|
+
label || showValue ? /* @__PURE__ */ jsxs51("div", { className: "mb-1 flex items-center justify-between gap-3 text-xs text-[var(--tapiz-text-muted)]", children: [
|
|
2562
|
+
label ? /* @__PURE__ */ jsx69("span", { children: label }) : /* @__PURE__ */ jsx69("span", {}),
|
|
2563
|
+
showValue ? /* @__PURE__ */ jsxs51("span", { className: "font-mono", children: [
|
|
2564
|
+
Math.round(percentage),
|
|
2565
|
+
"%"
|
|
2566
|
+
] }) : null
|
|
2567
|
+
] }) : null,
|
|
2568
|
+
/* @__PURE__ */ jsx69("div", { className: "h-2 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)]", children: /* @__PURE__ */ jsx69("div", { className: `h-full ${tones[tone2]}`, style: { width: `${percentage}%` } }) })
|
|
2569
|
+
] });
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
// src/components/shared/Avatar.tsx
|
|
2573
|
+
import { jsx as jsx70 } from "react/jsx-runtime";
|
|
2574
|
+
var sizes = { xs: "size-6 text-[10px]", sm: "size-8 text-xs", md: "size-10 text-sm", lg: "size-14 text-base" };
|
|
2575
|
+
function Avatar({ src, name = "?", size = "md", className = "" }) {
|
|
2576
|
+
const initials = name.split(" ").filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase()).join("") || "?";
|
|
2577
|
+
return src ? /* @__PURE__ */ jsx70("img", { src, alt: name, className: `border border-[var(--tapiz-border-strong)] object-cover ${sizes[size]} ${className}` }) : /* @__PURE__ */ jsx70("span", { className: `inline-grid place-items-center border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)] font-mono font-bold text-[var(--tapiz-accent)] ${sizes[size]} ${className}`, children: initials });
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
// src/components/shared/Kbd.tsx
|
|
2581
|
+
import { jsx as jsx71 } from "react/jsx-runtime";
|
|
2582
|
+
function Kbd({ children, className = "" }) {
|
|
2583
|
+
return /* @__PURE__ */ jsx71("kbd", { className: `inline-flex min-w-5 items-center justify-center border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)] px-1.5 py-0.5 font-mono text-[10px] font-bold text-[var(--tapiz-text-secondary)] shadow-[1px_1px_0_var(--tapiz-border-strong)] ${className}`, children });
|
|
2584
|
+
}
|
|
2585
|
+
|
|
2586
|
+
// src/components/shared/Timeline.tsx
|
|
2587
|
+
import { jsx as jsx72, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
2588
|
+
var tones2 = {
|
|
2589
|
+
neutral: "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-muted)]",
|
|
2590
|
+
info: "border-[var(--tapiz-info)] bg-[var(--tapiz-info-soft)] text-[var(--tapiz-info)]",
|
|
2591
|
+
success: "border-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)] text-[var(--tapiz-success)]",
|
|
2592
|
+
warning: "border-[var(--tapiz-warning)] bg-[var(--tapiz-warning-soft)] text-[var(--tapiz-warning)]",
|
|
2593
|
+
danger: "border-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)] text-[var(--tapiz-danger)]"
|
|
2594
|
+
};
|
|
2595
|
+
function Timeline({ items, className = "" }) {
|
|
2596
|
+
return /* @__PURE__ */ jsx72("ol", { className: `relative space-y-4 before:absolute before:left-4 before:top-2 before:h-[calc(100%-1rem)] before:w-px before:bg-[var(--tapiz-border-subtle)] ${className}`, children: items.map((item) => /* @__PURE__ */ jsxs52("li", { className: "relative flex gap-3", children: [
|
|
2597
|
+
/* @__PURE__ */ jsx72("span", { className: `z-10 grid size-8 shrink-0 place-items-center border text-xs ${tones2[item.tone ?? "neutral"]}`, children: item.icon ?? "\u2022" }),
|
|
2598
|
+
/* @__PURE__ */ jsxs52("span", { className: "min-w-0 flex-1 pb-2", children: [
|
|
2599
|
+
/* @__PURE__ */ jsxs52("span", { className: "flex flex-wrap items-baseline justify-between gap-2", children: [
|
|
2600
|
+
/* @__PURE__ */ jsx72("span", { className: "font-semibold text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
2601
|
+
item.time ? /* @__PURE__ */ jsx72("span", { className: "font-mono text-[10px] uppercase tracking-[0.14em] text-[var(--tapiz-text-muted)]", children: item.time }) : null
|
|
2602
|
+
] }),
|
|
2603
|
+
item.description ? /* @__PURE__ */ jsx72("span", { className: "mt-1 block text-sm text-[var(--tapiz-text-secondary)]", children: item.description }) : null
|
|
2604
|
+
] })
|
|
2605
|
+
] }, item.id)) });
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
// src/components/shared/KeyValueList.tsx
|
|
2609
|
+
import { jsx as jsx73, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
2610
|
+
function KeyValueList({ items, className = "", density = "normal" }) {
|
|
2611
|
+
return /* @__PURE__ */ jsx73("dl", { className: `divide-y divide-[var(--tapiz-border-subtle)] border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] ${className}`, children: items.map((item, index) => /* @__PURE__ */ jsxs53("div", { className: `grid gap-2 ${density === "compact" ? "p-3 md:grid-cols-[160px_1fr]" : "p-4 md:grid-cols-[220px_1fr]"}`, children: [
|
|
2612
|
+
/* @__PURE__ */ jsx73("dt", { className: "font-mono text-[10px] font-bold uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: item.keyLabel }),
|
|
2613
|
+
/* @__PURE__ */ jsxs53("dd", { children: [
|
|
2614
|
+
/* @__PURE__ */ jsx73("div", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: item.value }),
|
|
2615
|
+
item.description ? /* @__PURE__ */ jsx73("div", { className: "mt-1 text-xs text-[var(--tapiz-text-muted)]", children: item.description }) : null
|
|
2616
|
+
] })
|
|
2617
|
+
] }, index)) });
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2620
|
+
// src/components/shared/CodeBlock.tsx
|
|
2621
|
+
import { jsx as jsx74, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
2622
|
+
function CodeBlock({ children, language, title, actions, className = "" }) {
|
|
2623
|
+
return /* @__PURE__ */ jsxs54("figure", { className: `overflow-hidden border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] ${className}`, children: [
|
|
2624
|
+
title || language || actions ? /* @__PURE__ */ jsxs54("figcaption", { className: "flex items-center justify-between gap-3 border-b border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)] px-3 py-2", children: [
|
|
2625
|
+
/* @__PURE__ */ jsx74("span", { className: "font-mono text-[10px] font-bold uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: title ?? language }),
|
|
2626
|
+
actions
|
|
2627
|
+
] }) : null,
|
|
2628
|
+
/* @__PURE__ */ jsx74("pre", { className: "overflow-auto p-4 text-sm leading-6 text-[var(--tapiz-text-secondary)]", children: /* @__PURE__ */ jsx74("code", { children }) })
|
|
2629
|
+
] });
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
// src/components/marketing/LogoCloud.tsx
|
|
2633
|
+
import { jsx as jsx75, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
2634
|
+
function LogoCloud({ title, items, className = "" }) {
|
|
2635
|
+
return /* @__PURE__ */ jsx75("section", { className: `border-y border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] py-8 ${className}`, children: /* @__PURE__ */ jsxs55("div", { className: "mx-auto max-w-7xl px-[var(--tapiz-space-page-x)]", children: [
|
|
2636
|
+
title ? /* @__PURE__ */ jsx75("p", { className: "mb-6 text-center font-mono text-[10px] font-bold uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: title }) : null,
|
|
2637
|
+
/* @__PURE__ */ jsx75("div", { className: "grid grid-cols-2 gap-3 md:grid-cols-4 lg:grid-cols-6", children: items.map((item) => /* @__PURE__ */ jsx75("div", { className: "grid min-h-20 place-items-center border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)] px-4 text-center text-sm font-semibold text-[var(--tapiz-text-secondary)]", children: item.logo ?? item.name }, item.name)) })
|
|
2638
|
+
] }) });
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
// src/components/marketing/TestimonialCard.tsx
|
|
2642
|
+
import { jsx as jsx76, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
2643
|
+
function TestimonialCard({ quote, author, role, avatarSrc, className = "", variant = "surface" }) {
|
|
2644
|
+
return /* @__PURE__ */ jsxs56("figure", { className: `border bg-[var(--tapiz-bg-surface)] p-5 ${variant === "brutal" ? "border-2 border-[var(--tapiz-border-strong)] shadow-[var(--tapiz-shadow-brutal)]" : "border-[var(--tapiz-border-subtle)] shadow-[var(--tapiz-shadow-sm)]"} ${className}`, children: [
|
|
2645
|
+
/* @__PURE__ */ jsxs56("blockquote", { className: "text-base leading-7 text-[var(--tapiz-text-secondary)]", children: [
|
|
2646
|
+
"\u201C",
|
|
2647
|
+
quote,
|
|
2648
|
+
"\u201D"
|
|
2649
|
+
] }),
|
|
2650
|
+
/* @__PURE__ */ jsxs56("figcaption", { className: "mt-5 flex items-center gap-3", children: [
|
|
2651
|
+
/* @__PURE__ */ jsx76(Avatar, { name: author, src: avatarSrc, size: "sm" }),
|
|
2652
|
+
/* @__PURE__ */ jsxs56("span", { children: [
|
|
2653
|
+
/* @__PURE__ */ jsx76("span", { className: "block text-sm font-semibold text-[var(--tapiz-text-primary)]", children: author }),
|
|
2654
|
+
role ? /* @__PURE__ */ jsx76("span", { className: "block text-xs text-[var(--tapiz-text-muted)]", children: role }) : null
|
|
2655
|
+
] })
|
|
2656
|
+
] })
|
|
2657
|
+
] });
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
// src/components/marketing/PricingCard.tsx
|
|
2661
|
+
import { jsx as jsx77, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
2662
|
+
function PricingCard({ name, price, description, features = [], cta, highlighted = false, className = "" }) {
|
|
2663
|
+
return /* @__PURE__ */ jsxs57("section", { className: `flex h-full flex-col border bg-[var(--tapiz-bg-surface)] p-6 ${highlighted ? "border-2 border-[var(--tapiz-border-strong)] shadow-[var(--tapiz-shadow-brutal-lg)]" : "border-[var(--tapiz-border-subtle)] shadow-[var(--tapiz-shadow-sm)]"} ${className}`, children: [
|
|
2664
|
+
/* @__PURE__ */ jsxs57("div", { className: "flex-1", children: [
|
|
2665
|
+
/* @__PURE__ */ jsx77("h3", { className: "text-lg font-semibold text-[var(--tapiz-text-primary)]", children: name }),
|
|
2666
|
+
description ? /* @__PURE__ */ jsx77("p", { className: "mt-2 text-sm text-[var(--tapiz-text-muted)]", children: description }) : null,
|
|
2667
|
+
/* @__PURE__ */ jsx77("div", { className: "mt-6 text-4xl font-semibold tracking-tight text-[var(--tapiz-text-primary)]", children: price }),
|
|
2668
|
+
/* @__PURE__ */ jsx77("ul", { className: "mt-6 space-y-3 text-sm text-[var(--tapiz-text-secondary)]", children: features.map((feature, index) => /* @__PURE__ */ jsxs57("li", { className: "flex gap-2", children: [
|
|
2669
|
+
/* @__PURE__ */ jsx77("span", { className: "text-[var(--tapiz-success)]", children: "\u2713" }),
|
|
2670
|
+
/* @__PURE__ */ jsx77("span", { children: feature })
|
|
2671
|
+
] }, index)) })
|
|
2672
|
+
] }),
|
|
2673
|
+
/* @__PURE__ */ jsx77("div", { className: "mt-6", children: cta ?? /* @__PURE__ */ jsx77(Button, { variant: highlighted ? "primary" : "secondary", fullWidth: true, children: "Get started" }) })
|
|
2674
|
+
] });
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
// src/components/marketing/StatsBand.tsx
|
|
2678
|
+
import { jsx as jsx78, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
2679
|
+
function StatsBand({ items, className = "" }) {
|
|
2680
|
+
return /* @__PURE__ */ jsx78("section", { className: `border-y border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-inverse)] text-[var(--tapiz-text-inverse)] ${className}`, children: /* @__PURE__ */ jsx78("div", { className: "mx-auto grid max-w-7xl divide-y divide-[color-mix(in_srgb,var(--tapiz-text-inverse)_24%,transparent)] px-[var(--tapiz-space-page-x)] md:grid-cols-3 md:divide-x md:divide-y-0", children: items.map((item, index) => /* @__PURE__ */ jsxs58("div", { className: "p-6 md:p-8", children: [
|
|
2681
|
+
/* @__PURE__ */ jsx78("div", { className: "text-3xl font-semibold tracking-tight", children: item.value }),
|
|
2682
|
+
/* @__PURE__ */ jsx78("div", { className: "mt-2 font-mono text-[10px] font-bold uppercase tracking-[0.18em] opacity-70", children: item.label }),
|
|
2683
|
+
item.description ? /* @__PURE__ */ jsx78("div", { className: "mt-3 text-sm opacity-70", children: item.description }) : null
|
|
2684
|
+
] }, index)) }) });
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
// src/presets/framework.ts
|
|
2688
|
+
var tapizFrameworkPresets = {
|
|
2689
|
+
enterprise: {
|
|
2690
|
+
shell: "tapiz-enterprise-shell",
|
|
2691
|
+
card: "tapiz-enterprise-card",
|
|
2692
|
+
button: "primary",
|
|
2693
|
+
density: "comfortable"
|
|
2694
|
+
},
|
|
2695
|
+
brutal: {
|
|
2696
|
+
shell: "tapiz-enterprise-shell tapiz-grid-bg",
|
|
2697
|
+
card: "tapiz-brutal-card",
|
|
2698
|
+
button: "brutal",
|
|
2699
|
+
density: "comfortable"
|
|
2700
|
+
},
|
|
2701
|
+
dashboard: {
|
|
2702
|
+
shell: "tapiz-enterprise-shell",
|
|
2703
|
+
card: "stat-card",
|
|
2704
|
+
button: "secondary",
|
|
2705
|
+
density: "compact"
|
|
2706
|
+
},
|
|
2707
|
+
marketing: {
|
|
2708
|
+
shell: "tapiz-enterprise-shell tapiz-noise-bg",
|
|
2709
|
+
card: "tapiz-enterprise-card",
|
|
2710
|
+
button: "primary",
|
|
2711
|
+
density: "spacious"
|
|
2712
|
+
},
|
|
2713
|
+
compact: {
|
|
2714
|
+
shell: "tapiz-enterprise-shell",
|
|
2715
|
+
card: "card",
|
|
2716
|
+
button: "secondary",
|
|
2717
|
+
density: "compact"
|
|
2718
|
+
}
|
|
2719
|
+
};
|
|
2720
|
+
|
|
2721
|
+
// src/components/layout/Container.tsx
|
|
2722
|
+
import { jsx as jsx79 } from "react/jsx-runtime";
|
|
2723
|
+
var sizeClasses2 = {
|
|
2724
|
+
sm: "max-w-3xl",
|
|
2725
|
+
md: "max-w-5xl",
|
|
2726
|
+
lg: "max-w-7xl",
|
|
2727
|
+
xl: "max-w-[90rem]",
|
|
2728
|
+
full: "max-w-none"
|
|
2729
|
+
};
|
|
2730
|
+
function Container({ children, size = "lg", padded = true, className = "", style }) {
|
|
2731
|
+
return /* @__PURE__ */ jsx79(
|
|
2732
|
+
"div",
|
|
2733
|
+
{
|
|
2734
|
+
className: ["mx-auto w-full", sizeClasses2[size], padded ? "px-[var(--tapiz-space-page-x)]" : "", className].filter(Boolean).join(" "),
|
|
2735
|
+
style,
|
|
2736
|
+
children
|
|
2737
|
+
}
|
|
2738
|
+
);
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
// src/components/layout/Surface.tsx
|
|
2742
|
+
import { jsx as jsx80 } from "react/jsx-runtime";
|
|
2743
|
+
var variantClasses5 = {
|
|
2744
|
+
canvas: "bg-[var(--tapiz-bg-page)] text-[var(--tapiz-text-primary)]",
|
|
2745
|
+
surface: "bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-primary)]",
|
|
2746
|
+
raised: "bg-[var(--tapiz-bg-surface-raised)] text-[var(--tapiz-text-primary)] shadow-[var(--tapiz-shadow-md)]",
|
|
2747
|
+
muted: "bg-[var(--tapiz-bg-surface-muted)] text-[var(--tapiz-text-primary)]",
|
|
2748
|
+
brutal: "bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-primary)] border-2 border-[var(--tapiz-border-strong)] shadow-[var(--tapiz-shadow-brutal)]",
|
|
2749
|
+
inverse: "bg-[var(--tapiz-bg-surface-inverse)] text-[var(--tapiz-text-inverse)]"
|
|
2750
|
+
};
|
|
2751
|
+
var paddingClasses2 = {
|
|
2752
|
+
none: "p-0",
|
|
2753
|
+
sm: "p-3",
|
|
2754
|
+
md: "p-5",
|
|
2755
|
+
lg: "p-6",
|
|
2756
|
+
xl: "p-8"
|
|
2757
|
+
};
|
|
2758
|
+
function Surface({ children, variant = "surface", padding = "md", bordered = true, className = "", style }) {
|
|
2759
|
+
return /* @__PURE__ */ jsx80(
|
|
2760
|
+
"section",
|
|
2761
|
+
{
|
|
2762
|
+
className: [variantClasses5[variant], paddingClasses2[padding], bordered && variant !== "brutal" ? "border border-[var(--tapiz-border-subtle)]" : "", className].filter(Boolean).join(" "),
|
|
2763
|
+
style,
|
|
2764
|
+
children
|
|
2765
|
+
}
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
// src/components/layout/Divider.tsx
|
|
2770
|
+
import { jsx as jsx81, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
2771
|
+
function Divider({ orientation = "horizontal", label, className = "" }) {
|
|
2772
|
+
if (orientation === "vertical") {
|
|
2773
|
+
return /* @__PURE__ */ jsx81("div", { className: `mx-2 min-h-6 w-px bg-[var(--tapiz-border-subtle)] ${className}`, "aria-hidden": "true" });
|
|
2774
|
+
}
|
|
2775
|
+
if (label) {
|
|
2776
|
+
return /* @__PURE__ */ jsxs59("div", { className: `flex items-center gap-3 ${className}`, children: [
|
|
2777
|
+
/* @__PURE__ */ jsx81("div", { className: "h-px flex-1 bg-[var(--tapiz-border-subtle)]" }),
|
|
2778
|
+
/* @__PURE__ */ jsx81("span", { className: "font-mono text-[10px] uppercase tracking-[0.18em] text-[var(--tapiz-text-muted)]", children: label }),
|
|
2779
|
+
/* @__PURE__ */ jsx81("div", { className: "h-px flex-1 bg-[var(--tapiz-border-subtle)]" })
|
|
2780
|
+
] });
|
|
2781
|
+
}
|
|
2782
|
+
return /* @__PURE__ */ jsx81("hr", { className: `border-[var(--tapiz-border-subtle)] ${className}` });
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
// src/components/layout/ResponsiveGrid.tsx
|
|
2786
|
+
import { jsx as jsx82 } from "react/jsx-runtime";
|
|
2787
|
+
var gapClasses3 = {
|
|
2788
|
+
sm: "gap-3",
|
|
2789
|
+
md: "gap-4",
|
|
2790
|
+
lg: "gap-6",
|
|
2791
|
+
xl: "gap-8"
|
|
2792
|
+
};
|
|
2793
|
+
function ResponsiveGrid({ children, min = "18rem", gap = "md", className = "", style }) {
|
|
2794
|
+
return /* @__PURE__ */ jsx82(
|
|
2795
|
+
"div",
|
|
2796
|
+
{
|
|
2797
|
+
className: `grid ${gapClasses3[gap]} ${className}`,
|
|
2798
|
+
style: { gridTemplateColumns: `repeat(auto-fit, minmax(${min}, 1fr))`, ...style },
|
|
2799
|
+
children
|
|
2800
|
+
}
|
|
2801
|
+
);
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
// src/components/data-display/Sparkline.tsx
|
|
2805
|
+
import { jsx as jsx83, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
2806
|
+
function Sparkline({ values, width = 160, height = 48, label = "Trend", className = "", style }) {
|
|
2807
|
+
const safeValues = values.length ? values : [0];
|
|
2808
|
+
const min = Math.min(...safeValues);
|
|
2809
|
+
const max = Math.max(...safeValues);
|
|
2810
|
+
const range = max - min || 1;
|
|
2811
|
+
const step = safeValues.length > 1 ? width / (safeValues.length - 1) : width;
|
|
2812
|
+
const points = safeValues.map((value, index) => {
|
|
2813
|
+
const x = index * step;
|
|
2814
|
+
const y = height - (value - min) / range * (height - 6) - 3;
|
|
2815
|
+
return `${x},${y}`;
|
|
2816
|
+
}).join(" ");
|
|
2817
|
+
return /* @__PURE__ */ jsxs60("svg", { className, style, width, height, viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": label, children: [
|
|
2818
|
+
/* @__PURE__ */ jsx83("polyline", { points, fill: "none", stroke: "var(--tapiz-accent)", strokeWidth: "2", strokeLinecap: "square", strokeLinejoin: "miter" }),
|
|
2819
|
+
/* @__PURE__ */ jsx83("line", { x1: "0", x2: width, y1: height - 1, y2: height - 1, stroke: "var(--tapiz-border-subtle)", strokeWidth: "1" })
|
|
2820
|
+
] });
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
// src/components/data-display/BarList.tsx
|
|
2824
|
+
import { jsx as jsx84, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
2825
|
+
function BarList({ items, max, valueFormatter = (value) => value, className = "" }) {
|
|
2826
|
+
const computedMax = max ?? Math.max(1, ...items.map((item) => item.value));
|
|
2827
|
+
return /* @__PURE__ */ jsx84("div", { className: `space-y-3 ${className}`, children: items.map((item, index) => {
|
|
2828
|
+
const percent = Math.max(0, Math.min(100, item.value / computedMax * 100));
|
|
2829
|
+
return /* @__PURE__ */ jsxs61("div", { children: [
|
|
2830
|
+
/* @__PURE__ */ jsxs61("div", { className: "mb-1 flex items-center justify-between gap-3 text-sm", children: [
|
|
2831
|
+
/* @__PURE__ */ jsx84("span", { className: "font-medium text-[var(--tapiz-text-secondary)]", children: item.label }),
|
|
2832
|
+
/* @__PURE__ */ jsx84("span", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: valueFormatter(item.value) })
|
|
2833
|
+
] }),
|
|
2834
|
+
/* @__PURE__ */ jsx84("div", { className: "h-2 border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)]", children: /* @__PURE__ */ jsx84("div", { className: "h-full bg-[var(--tapiz-accent)]", style: { width: `${percent}%` } }) }),
|
|
2835
|
+
item.detail ? /* @__PURE__ */ jsx84("div", { className: "mt-1 text-xs text-[var(--tapiz-text-muted)]", children: item.detail }) : null
|
|
2836
|
+
] }, index);
|
|
2837
|
+
}) });
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
// src/components/data-display/DonutMetric.tsx
|
|
2841
|
+
import { jsx as jsx85, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
2842
|
+
function DonutMetric({ value, max = 100, label, caption, size = 112, className = "" }) {
|
|
2843
|
+
const radius = 42;
|
|
2844
|
+
const circumference = 2 * Math.PI * radius;
|
|
2845
|
+
const ratio = Math.max(0, Math.min(1, value / max));
|
|
2846
|
+
const offset = circumference * (1 - ratio);
|
|
2847
|
+
return /* @__PURE__ */ jsxs62("div", { className: `inline-flex items-center gap-4 ${className}`, children: [
|
|
2848
|
+
/* @__PURE__ */ jsxs62("svg", { width: size, height: size, viewBox: "0 0 112 112", role: "img", "aria-label": `${Math.round(ratio * 100)}%`, children: [
|
|
2849
|
+
/* @__PURE__ */ jsx85("circle", { cx: "56", cy: "56", r: radius, fill: "none", stroke: "var(--tapiz-border-subtle)", strokeWidth: "10" }),
|
|
2850
|
+
/* @__PURE__ */ jsx85(
|
|
2851
|
+
"circle",
|
|
2852
|
+
{
|
|
2853
|
+
cx: "56",
|
|
2854
|
+
cy: "56",
|
|
2855
|
+
r: radius,
|
|
2856
|
+
fill: "none",
|
|
2857
|
+
stroke: "var(--tapiz-accent)",
|
|
2858
|
+
strokeWidth: "10",
|
|
2859
|
+
strokeDasharray: circumference,
|
|
2860
|
+
strokeDashoffset: offset,
|
|
2861
|
+
strokeLinecap: "square",
|
|
2862
|
+
transform: "rotate(-90 56 56)"
|
|
2863
|
+
}
|
|
2864
|
+
),
|
|
2865
|
+
/* @__PURE__ */ jsxs62("text", { x: "56", y: "61", textAnchor: "middle", className: "fill-[var(--tapiz-text-primary)] font-mono text-lg font-bold", children: [
|
|
2866
|
+
Math.round(ratio * 100),
|
|
2867
|
+
"%"
|
|
2868
|
+
] })
|
|
2869
|
+
] }),
|
|
2870
|
+
label || caption ? /* @__PURE__ */ jsxs62("div", { children: [
|
|
2871
|
+
label ? /* @__PURE__ */ jsx85("div", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: label }) : null,
|
|
2872
|
+
caption ? /* @__PURE__ */ jsx85("div", { className: "mt-1 text-xs leading-5 text-[var(--tapiz-text-muted)]", children: caption }) : null
|
|
2873
|
+
] }) : null
|
|
2874
|
+
] });
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
// src/components/data-display/FilterChip.tsx
|
|
2878
|
+
import { jsx as jsx86, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
2879
|
+
function FilterChip({ children, active = false, onRemove, className = "" }) {
|
|
2880
|
+
return /* @__PURE__ */ jsxs63(
|
|
2881
|
+
"span",
|
|
2882
|
+
{
|
|
2883
|
+
className: [
|
|
2884
|
+
"inline-flex items-center gap-2 border px-2.5 py-1 font-mono text-[11px] uppercase tracking-[0.12em]",
|
|
2885
|
+
active ? "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)] text-[var(--tapiz-text-primary)]" : "border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] text-[var(--tapiz-text-muted)]",
|
|
2886
|
+
className
|
|
2887
|
+
].join(" "),
|
|
2888
|
+
children: [
|
|
2889
|
+
children,
|
|
2890
|
+
onRemove ? /* @__PURE__ */ jsx86("button", { type: "button", onClick: onRemove, className: "text-[var(--tapiz-text-muted)] hover:text-[var(--tapiz-danger)]", "aria-label": "Remove filter", children: "\xD7" }) : null
|
|
2891
|
+
]
|
|
2892
|
+
}
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
// src/components/data-display/DataToolbar.tsx
|
|
2897
|
+
import { jsx as jsx87, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
2898
|
+
function DataToolbar({ title, description, search, filters, actions, className = "" }) {
|
|
2899
|
+
return /* @__PURE__ */ jsxs64("div", { className: `border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-4 ${className}`, children: [
|
|
2900
|
+
/* @__PURE__ */ jsxs64("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between", children: [
|
|
2901
|
+
/* @__PURE__ */ jsxs64("div", { children: [
|
|
2902
|
+
title ? /* @__PURE__ */ jsx87("h3", { className: "text-base font-semibold text-[var(--tapiz-text-primary)]", children: title }) : null,
|
|
2903
|
+
description ? /* @__PURE__ */ jsx87("p", { className: "mt-1 text-sm text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
2904
|
+
] }),
|
|
2905
|
+
actions ? /* @__PURE__ */ jsx87("div", { className: "flex flex-wrap gap-2", children: actions }) : null
|
|
2906
|
+
] }),
|
|
2907
|
+
search || filters ? /* @__PURE__ */ jsxs64("div", { className: "mt-4 flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between", children: [
|
|
2908
|
+
search ? /* @__PURE__ */ jsx87("div", { className: "min-w-0 flex-1", children: search }) : null,
|
|
2909
|
+
filters ? /* @__PURE__ */ jsx87("div", { className: "flex flex-wrap gap-2", children: filters }) : null
|
|
2910
|
+
] }) : null
|
|
2911
|
+
] });
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
// src/components/framework/ResourceCard.tsx
|
|
2915
|
+
import { Fragment as Fragment3, jsx as jsx88, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
2916
|
+
function ResourceCard({ title, description, eyebrow, icon, meta, status, actions, href, className = "" }) {
|
|
2917
|
+
const content = /* @__PURE__ */ jsxs65(Fragment3, { children: [
|
|
2918
|
+
/* @__PURE__ */ jsxs65("div", { className: "flex items-start justify-between gap-4", children: [
|
|
2919
|
+
/* @__PURE__ */ jsxs65("div", { className: "flex min-w-0 items-start gap-3", children: [
|
|
2920
|
+
icon ? /* @__PURE__ */ jsx88("div", { className: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)] p-2 text-[var(--tapiz-accent)]", children: icon }) : null,
|
|
2921
|
+
/* @__PURE__ */ jsxs65("div", { className: "min-w-0", children: [
|
|
2922
|
+
eyebrow ? /* @__PURE__ */ jsx88("div", { className: "kicker mb-2", children: eyebrow }) : null,
|
|
2923
|
+
/* @__PURE__ */ jsx88("h3", { className: "truncate text-base font-semibold text-[var(--tapiz-text-primary)]", children: title }),
|
|
2924
|
+
description ? /* @__PURE__ */ jsx88("p", { className: "mt-2 line-clamp-2 text-sm leading-6 text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
2925
|
+
] })
|
|
2926
|
+
] }),
|
|
2927
|
+
status ? /* @__PURE__ */ jsx88(Badge, { children: status }) : null
|
|
2928
|
+
] }),
|
|
2929
|
+
meta || actions ? /* @__PURE__ */ jsxs65("div", { className: "mt-5 flex flex-wrap items-center justify-between gap-3 border-t border-[var(--tapiz-border-subtle)] pt-4", children: [
|
|
2930
|
+
meta ? /* @__PURE__ */ jsx88("div", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: meta }) : /* @__PURE__ */ jsx88("span", {}),
|
|
2931
|
+
actions ? /* @__PURE__ */ jsx88("div", { className: "flex flex-wrap gap-2", children: actions }) : null
|
|
2932
|
+
] }) : null
|
|
2933
|
+
] });
|
|
2934
|
+
const classes = `block border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-5 shadow-[var(--tapiz-shadow-sm)] hover:border-[var(--tapiz-border-strong)] hover:shadow-[var(--tapiz-shadow-md)] ${className}`;
|
|
2935
|
+
return href ? /* @__PURE__ */ jsx88("a", { href, className: classes, children: content }) : /* @__PURE__ */ jsx88("article", { className: classes, children: content });
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
// src/components/framework/IntegrationCard.tsx
|
|
2939
|
+
import { jsx as jsx89, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
2940
|
+
var statusLabel = {
|
|
2941
|
+
connected: "Connected",
|
|
2942
|
+
disconnected: "Disconnected",
|
|
2943
|
+
syncing: "Syncing",
|
|
2944
|
+
error: "Error"
|
|
2945
|
+
};
|
|
2946
|
+
var statusVariant = {
|
|
2947
|
+
connected: "success",
|
|
2948
|
+
disconnected: "default",
|
|
2949
|
+
syncing: "info",
|
|
2950
|
+
error: "danger"
|
|
2951
|
+
};
|
|
2952
|
+
function IntegrationCard({ name, description, logo, status = "disconnected", lastSync, actions, className = "" }) {
|
|
2953
|
+
return /* @__PURE__ */ jsxs66("article", { className: `border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-5 ${className}`, children: [
|
|
2954
|
+
/* @__PURE__ */ jsxs66("div", { className: "flex items-start justify-between gap-4", children: [
|
|
2955
|
+
/* @__PURE__ */ jsxs66("div", { className: "flex items-start gap-3", children: [
|
|
2956
|
+
/* @__PURE__ */ jsx89("div", { className: "flex size-11 items-center justify-center border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)] text-[var(--tapiz-accent)]", children: logo ?? /* @__PURE__ */ jsx89("span", { className: "font-mono text-xs", children: "API" }) }),
|
|
2957
|
+
/* @__PURE__ */ jsxs66("div", { children: [
|
|
2958
|
+
/* @__PURE__ */ jsx89("h3", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: name }),
|
|
2959
|
+
description ? /* @__PURE__ */ jsx89("p", { className: "mt-1 text-sm leading-5 text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
2960
|
+
] })
|
|
2961
|
+
] }),
|
|
2962
|
+
/* @__PURE__ */ jsx89(StatusBadge, { variant: statusVariant[status], label: statusLabel[status] })
|
|
2963
|
+
] }),
|
|
2964
|
+
/* @__PURE__ */ jsxs66("div", { className: "mt-5 flex flex-wrap items-center justify-between gap-3 border-t border-[var(--tapiz-border-subtle)] pt-4", children: [
|
|
2965
|
+
/* @__PURE__ */ jsx89("div", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: lastSync ?? "No sync yet" }),
|
|
2966
|
+
actions ? /* @__PURE__ */ jsx89("div", { className: "flex gap-2", children: actions }) : null
|
|
2967
|
+
] })
|
|
2968
|
+
] });
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
// src/components/framework/HealthIndicator.tsx
|
|
2972
|
+
import { jsx as jsx90, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
2973
|
+
var toneClasses2 = {
|
|
2974
|
+
operational: "bg-[var(--tapiz-success)]",
|
|
2975
|
+
degraded: "bg-[var(--tapiz-warning)]",
|
|
2976
|
+
outage: "bg-[var(--tapiz-danger)]",
|
|
2977
|
+
unknown: "bg-[var(--tapiz-text-disabled)]"
|
|
2978
|
+
};
|
|
2979
|
+
var defaultLabel = {
|
|
2980
|
+
operational: "Operational",
|
|
2981
|
+
degraded: "Degraded",
|
|
2982
|
+
outage: "Outage",
|
|
2983
|
+
unknown: "Unknown"
|
|
2984
|
+
};
|
|
2985
|
+
function HealthIndicator({ tone: tone2 = "unknown", label, detail, className = "" }) {
|
|
2986
|
+
return /* @__PURE__ */ jsxs67("div", { className: `inline-flex items-center gap-3 border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] px-3 py-2 ${className}`, children: [
|
|
2987
|
+
/* @__PURE__ */ jsx90("span", { className: `size-2.5 ${toneClasses2[tone2]}`, "aria-hidden": "true" }),
|
|
2988
|
+
/* @__PURE__ */ jsx90("span", { className: "text-sm font-medium text-[var(--tapiz-text-primary)]", children: label ?? defaultLabel[tone2] }),
|
|
2989
|
+
detail ? /* @__PURE__ */ jsx90("span", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: detail }) : null
|
|
2990
|
+
] });
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2993
|
+
// src/components/framework/AuditLog.tsx
|
|
2994
|
+
import { jsx as jsx91, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
2995
|
+
function AuditLog({ items, className = "" }) {
|
|
2996
|
+
return /* @__PURE__ */ jsx91("div", { className: `divide-y divide-[var(--tapiz-border-subtle)] border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] ${className}`, children: items.map((item, index) => /* @__PURE__ */ jsxs68("div", { className: "flex gap-3 p-4", children: [
|
|
2997
|
+
/* @__PURE__ */ jsx91(Avatar, { name: item.initials ?? item.actor, size: "sm" }),
|
|
2998
|
+
/* @__PURE__ */ jsxs68("div", { className: "min-w-0 flex-1", children: [
|
|
2999
|
+
/* @__PURE__ */ jsxs68("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
3000
|
+
/* @__PURE__ */ jsxs68("p", { className: "text-sm text-[var(--tapiz-text-secondary)]", children: [
|
|
3001
|
+
/* @__PURE__ */ jsx91("strong", { className: "text-[var(--tapiz-text-primary)]", children: item.actor }),
|
|
3002
|
+
" ",
|
|
3003
|
+
item.action
|
|
3004
|
+
] }),
|
|
3005
|
+
/* @__PURE__ */ jsx91("span", { className: "font-mono text-[11px] text-[var(--tapiz-text-muted)]", children: item.timestamp })
|
|
3006
|
+
] }),
|
|
3007
|
+
item.detail ? /* @__PURE__ */ jsx91("div", { className: "mt-1 text-xs leading-5 text-[var(--tapiz-text-muted)]", children: item.detail }) : null
|
|
3008
|
+
] })
|
|
3009
|
+
] }, index)) });
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
// src/components/framework/KanbanBoard.tsx
|
|
3013
|
+
import { jsx as jsx92, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
3014
|
+
var toneClasses3 = {
|
|
3015
|
+
default: "border-[var(--tapiz-border-subtle)]",
|
|
3016
|
+
accent: "border-[var(--tapiz-accent)]",
|
|
3017
|
+
success: "border-[var(--tapiz-success)]",
|
|
3018
|
+
warning: "border-[var(--tapiz-warning)]",
|
|
3019
|
+
danger: "border-[var(--tapiz-danger)]"
|
|
3020
|
+
};
|
|
3021
|
+
function KanbanBoard({ columns, className = "" }) {
|
|
3022
|
+
return /* @__PURE__ */ jsx92("div", { className: `grid gap-4 overflow-x-auto md:grid-flow-col md:auto-cols-[minmax(18rem,1fr)] ${className}`, children: columns.map((column) => /* @__PURE__ */ jsxs69("section", { className: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)] p-3", children: [
|
|
3023
|
+
/* @__PURE__ */ jsxs69("div", { className: "mb-3 flex items-start justify-between gap-3", children: [
|
|
3024
|
+
/* @__PURE__ */ jsxs69("div", { children: [
|
|
3025
|
+
/* @__PURE__ */ jsx92("h3", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: column.title }),
|
|
3026
|
+
column.description ? /* @__PURE__ */ jsx92("p", { className: "mt-1 text-xs text-[var(--tapiz-text-muted)]", children: column.description }) : null
|
|
3027
|
+
] }),
|
|
3028
|
+
/* @__PURE__ */ jsx92("span", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: column.items.length })
|
|
3029
|
+
] }),
|
|
3030
|
+
/* @__PURE__ */ jsx92("div", { className: "space-y-3", children: column.items.map((item) => /* @__PURE__ */ jsxs69("article", { className: `border-l-2 bg-[var(--tapiz-bg-surface)] p-3 shadow-[var(--tapiz-shadow-sm)] ${toneClasses3[item.tone ?? "default"]}`, children: [
|
|
3031
|
+
/* @__PURE__ */ jsx92("h4", { className: "text-sm font-medium text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
3032
|
+
item.description ? /* @__PURE__ */ jsx92("p", { className: "mt-1 text-xs leading-5 text-[var(--tapiz-text-muted)]", children: item.description }) : null,
|
|
3033
|
+
item.meta ? /* @__PURE__ */ jsx92("div", { className: "mt-3 font-mono text-[11px] text-[var(--tapiz-text-muted)]", children: item.meta }) : null
|
|
3034
|
+
] }, item.id)) })
|
|
3035
|
+
] }, column.id)) });
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
// src/components/framework/AccessMatrix.tsx
|
|
3039
|
+
import { jsx as jsx93, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
3040
|
+
function AccessMatrix({ roles, permissions, className = "" }) {
|
|
3041
|
+
return /* @__PURE__ */ jsx93("div", { className: `overflow-x-auto border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] ${className}`, children: /* @__PURE__ */ jsxs70("table", { className: "min-w-full text-sm", children: [
|
|
3042
|
+
/* @__PURE__ */ jsx93("thead", { children: /* @__PURE__ */ jsxs70("tr", { children: [
|
|
3043
|
+
/* @__PURE__ */ jsx93("th", { className: "px-4 py-3 text-left", children: "Permission" }),
|
|
3044
|
+
roles.map((role) => /* @__PURE__ */ jsx93("th", { className: "px-4 py-3 text-center", children: role.label }, role.key))
|
|
3045
|
+
] }) }),
|
|
3046
|
+
/* @__PURE__ */ jsx93("tbody", { children: permissions.map((permission) => /* @__PURE__ */ jsxs70("tr", { children: [
|
|
3047
|
+
/* @__PURE__ */ jsxs70("td", { className: "px-4 py-3", children: [
|
|
3048
|
+
/* @__PURE__ */ jsx93("div", { className: "font-medium text-[var(--tapiz-text-primary)]", children: permission.label }),
|
|
3049
|
+
permission.description ? /* @__PURE__ */ jsx93("div", { className: "mt-1 text-xs text-[var(--tapiz-text-muted)]", children: permission.description }) : null
|
|
3050
|
+
] }),
|
|
3051
|
+
roles.map((role) => /* @__PURE__ */ jsx93("td", { className: "px-4 py-3 text-center", children: /* @__PURE__ */ jsx93("span", { className: permission.roles[role.key] ? "text-[var(--tapiz-success)]" : "text-[var(--tapiz-text-disabled)]", children: permission.roles[role.key] ? "\u2713" : "\u2014" }) }, role.key))
|
|
3052
|
+
] }, permission.key)) })
|
|
3053
|
+
] }) });
|
|
3054
|
+
}
|
|
3055
|
+
|
|
3056
|
+
// src/components/framework/CalendarGrid.tsx
|
|
3057
|
+
import { jsx as jsx94, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
3058
|
+
var defaultWeekdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
3059
|
+
function CalendarGrid({ days, weekdays = defaultWeekdays, className = "" }) {
|
|
3060
|
+
return /* @__PURE__ */ jsxs71("div", { className: `border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] ${className}`, children: [
|
|
3061
|
+
/* @__PURE__ */ jsx94("div", { className: "grid grid-cols-7 border-b border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)]", children: weekdays.map((day, index) => /* @__PURE__ */ jsx94("div", { className: "px-3 py-2 font-mono text-[10px] uppercase tracking-[0.16em] text-[var(--tapiz-text-muted)]", children: day }, index)) }),
|
|
3062
|
+
/* @__PURE__ */ jsx94("div", { className: "grid grid-cols-7", children: days.map((day, index) => /* @__PURE__ */ jsxs71("div", { className: `min-h-28 border-b border-r border-[var(--tapiz-border-subtle)] p-2 ${day.muted ? "opacity-45" : ""} ${day.selected ? "bg-[var(--tapiz-accent-soft)]" : ""}`, children: [
|
|
3063
|
+
/* @__PURE__ */ jsxs71("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3064
|
+
/* @__PURE__ */ jsx94("span", { className: "font-mono text-xs text-[var(--tapiz-text-primary)]", children: day.date }),
|
|
3065
|
+
day.label ? /* @__PURE__ */ jsx94("span", { className: "text-[10px] text-[var(--tapiz-text-muted)]", children: day.label }) : null
|
|
3066
|
+
] }),
|
|
3067
|
+
day.events?.length ? /* @__PURE__ */ jsx94("div", { className: "mt-2 space-y-1", children: day.events.map((event, eventIndex) => /* @__PURE__ */ jsx94("div", { className: "truncate border-l-2 border-[var(--tapiz-accent)] bg-[var(--tapiz-bg-surface-muted)] px-2 py-1 text-[11px] text-[var(--tapiz-text-secondary)]", children: event }, eventIndex)) }) : null
|
|
3068
|
+
] }, index)) })
|
|
3069
|
+
] });
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// src/components/forms/Slider.tsx
|
|
3073
|
+
import { jsx as jsx95, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
3074
|
+
function Slider({ label, valueLabel, className = "", ...props }) {
|
|
3075
|
+
return /* @__PURE__ */ jsxs72("label", { className: `block ${className}`, children: [
|
|
3076
|
+
label || valueLabel ? /* @__PURE__ */ jsxs72("span", { className: "mb-2 flex items-center justify-between gap-3 text-sm", children: [
|
|
3077
|
+
label ? /* @__PURE__ */ jsx95("span", { className: "font-medium text-[var(--tapiz-text-secondary)]", children: label }) : /* @__PURE__ */ jsx95("span", {}),
|
|
3078
|
+
valueLabel ? /* @__PURE__ */ jsx95("span", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: valueLabel }) : null
|
|
3079
|
+
] }) : null,
|
|
3080
|
+
/* @__PURE__ */ jsx95(
|
|
3081
|
+
"input",
|
|
3082
|
+
{
|
|
3083
|
+
...props,
|
|
3084
|
+
type: "range",
|
|
3085
|
+
className: "h-2 w-full cursor-pointer appearance-none border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)] accent-[var(--tapiz-accent)]"
|
|
3086
|
+
}
|
|
3087
|
+
)
|
|
3088
|
+
] });
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3091
|
+
// src/components/forms/FileDropzone.tsx
|
|
3092
|
+
import { jsx as jsx96, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
3093
|
+
function FileDropzone({ title = "Drop files here", description, actionLabel = "Browse", className = "", ...props }) {
|
|
3094
|
+
return /* @__PURE__ */ jsxs73("label", { className: `block cursor-pointer border-2 border-dashed border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] p-6 text-center hover:bg-[var(--tapiz-bg-surface-muted)] ${className}`, children: [
|
|
3095
|
+
/* @__PURE__ */ jsx96("input", { ...props, type: "file", className: "sr-only" }),
|
|
3096
|
+
/* @__PURE__ */ jsx96("span", { className: "block text-sm font-semibold text-[var(--tapiz-text-primary)]", children: title }),
|
|
3097
|
+
description ? /* @__PURE__ */ jsx96("span", { className: "mt-2 block text-sm text-[var(--tapiz-text-muted)]", children: description }) : null,
|
|
3098
|
+
/* @__PURE__ */ jsx96("span", { className: "mt-4 inline-flex border border-[var(--tapiz-border-strong)] px-3 py-1.5 font-mono text-xs uppercase tracking-[0.12em] text-[var(--tapiz-accent)]", children: actionLabel })
|
|
3099
|
+
] });
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
// src/components/forms/PasswordInput.tsx
|
|
3103
|
+
import { jsx as jsx97, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
3104
|
+
function PasswordInput({ revealLabel = "Show", className = "", ...props }) {
|
|
3105
|
+
return /* @__PURE__ */ jsxs74("div", { className: `flex border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] focus-within:border-[var(--tapiz-border-focus)] focus-within:shadow-[inset_3px_0_0_0_var(--tapiz-signal)] ${className}`, children: [
|
|
3106
|
+
/* @__PURE__ */ jsx97(
|
|
3107
|
+
"input",
|
|
3108
|
+
{
|
|
3109
|
+
...props,
|
|
3110
|
+
type: "password",
|
|
3111
|
+
className: "min-w-0 flex-1 border-0 bg-transparent px-3 py-2 text-sm text-[var(--tapiz-text-primary)] outline-none"
|
|
3112
|
+
}
|
|
3113
|
+
),
|
|
3114
|
+
/* @__PURE__ */ jsx97("button", { type: "button", className: "border-l border-[var(--tapiz-border-subtle)] px-3 font-mono text-xs text-[var(--tapiz-text-muted)]", tabIndex: -1, children: revealLabel })
|
|
3115
|
+
] });
|
|
3116
|
+
}
|
|
3117
|
+
|
|
3118
|
+
// src/components/forms/TextareaCounter.tsx
|
|
3119
|
+
import { jsx as jsx98, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
3120
|
+
function TextareaCounter({ maxLength, value = "", className = "", ...props }) {
|
|
3121
|
+
const count = value.length;
|
|
3122
|
+
return /* @__PURE__ */ jsxs75("div", { className, children: [
|
|
3123
|
+
/* @__PURE__ */ jsx98("textarea", { ...props, value, maxLength, className: "input-field min-h-28" }),
|
|
3124
|
+
/* @__PURE__ */ jsxs75("div", { className: "mt-1 text-right font-mono text-[11px] text-[var(--tapiz-text-muted)]", children: [
|
|
3125
|
+
count,
|
|
3126
|
+
"/",
|
|
3127
|
+
maxLength
|
|
3128
|
+
] })
|
|
3129
|
+
] });
|
|
3130
|
+
}
|
|
3131
|
+
|
|
3132
|
+
// src/components/feedback/Callout.tsx
|
|
3133
|
+
import { jsx as jsx99, jsxs as jsxs76 } from "react/jsx-runtime";
|
|
3134
|
+
var toneClasses4 = {
|
|
3135
|
+
info: "border-[var(--tapiz-info)] bg-[var(--tapiz-info-soft)]",
|
|
3136
|
+
success: "border-[var(--tapiz-success)] bg-[var(--tapiz-success-soft)]",
|
|
3137
|
+
warning: "border-[var(--tapiz-warning)] bg-[var(--tapiz-warning-soft)]",
|
|
3138
|
+
danger: "border-[var(--tapiz-danger)] bg-[var(--tapiz-danger-soft)]",
|
|
3139
|
+
neutral: "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)]"
|
|
3140
|
+
};
|
|
3141
|
+
function Callout({ title, children, tone: tone2 = "info", icon, actions, className = "" }) {
|
|
3142
|
+
return /* @__PURE__ */ jsx99("aside", { className: `border-l-4 p-4 ${toneClasses4[tone2]} ${className}`, children: /* @__PURE__ */ jsxs76("div", { className: "flex gap-3", children: [
|
|
3143
|
+
icon ? /* @__PURE__ */ jsx99("div", { className: "text-[var(--tapiz-text-primary)]", children: icon }) : null,
|
|
3144
|
+
/* @__PURE__ */ jsxs76("div", { className: "min-w-0 flex-1", children: [
|
|
3145
|
+
title ? /* @__PURE__ */ jsx99("h3", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: title }) : null,
|
|
3146
|
+
children ? /* @__PURE__ */ jsx99("div", { className: "mt-1 text-sm leading-6 text-[var(--tapiz-text-secondary)]", children }) : null,
|
|
3147
|
+
actions ? /* @__PURE__ */ jsx99("div", { className: "mt-3 flex flex-wrap gap-2", children: actions }) : null
|
|
3148
|
+
] })
|
|
3149
|
+
] }) });
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
// src/components/feedback/LoadingOverlay.tsx
|
|
3153
|
+
import { jsx as jsx100, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
3154
|
+
function LoadingOverlay({ visible = false, label = "Loading", children, className = "" }) {
|
|
3155
|
+
return /* @__PURE__ */ jsxs77("div", { className: `relative ${className}`, children: [
|
|
3156
|
+
children,
|
|
3157
|
+
visible ? /* @__PURE__ */ jsx100("div", { className: "absolute inset-0 grid place-items-center border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-overlay)] backdrop-blur-sm", children: /* @__PURE__ */ jsxs77("div", { className: "flex items-center gap-3 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface)] px-4 py-3 text-sm text-[var(--tapiz-text-primary)] shadow-[var(--tapiz-shadow-brutal)]", children: [
|
|
3158
|
+
/* @__PURE__ */ jsx100(Spinner, {}),
|
|
3159
|
+
/* @__PURE__ */ jsx100("span", { children: label })
|
|
3160
|
+
] }) }) : null
|
|
3161
|
+
] });
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3164
|
+
// src/components/feedback/NotificationList.tsx
|
|
3165
|
+
import { jsx as jsx101, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
3166
|
+
function NotificationList({ items, className = "" }) {
|
|
3167
|
+
return /* @__PURE__ */ jsx101("div", { className: `divide-y divide-[var(--tapiz-border-subtle)] border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] ${className}`, children: items.map((item) => /* @__PURE__ */ jsxs78("article", { className: "flex gap-3 p-4", children: [
|
|
3168
|
+
/* @__PURE__ */ jsx101("span", { className: `mt-1 size-2.5 ${item.unread ? "bg-[var(--tapiz-accent)]" : "bg-[var(--tapiz-border-subtle)]"}`, "aria-hidden": "true" }),
|
|
3169
|
+
/* @__PURE__ */ jsxs78("div", { className: "min-w-0 flex-1", children: [
|
|
3170
|
+
/* @__PURE__ */ jsxs78("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3171
|
+
/* @__PURE__ */ jsx101("h3", { className: "text-sm font-medium text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
3172
|
+
item.time ? /* @__PURE__ */ jsx101("span", { className: "font-mono text-[11px] text-[var(--tapiz-text-muted)]", children: item.time }) : null
|
|
3173
|
+
] }),
|
|
3174
|
+
item.description ? /* @__PURE__ */ jsx101("p", { className: "mt-1 text-sm leading-5 text-[var(--tapiz-text-muted)]", children: item.description }) : null,
|
|
3175
|
+
item.action ? /* @__PURE__ */ jsx101("div", { className: "mt-3", children: item.action }) : null
|
|
3176
|
+
] })
|
|
3177
|
+
] }, item.id)) });
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
// src/components/layout/MasonryGrid.tsx
|
|
3181
|
+
import { jsx as jsx102 } from "react/jsx-runtime";
|
|
3182
|
+
var columnClasses = { 2: "md:columns-2", 3: "md:columns-2 xl:columns-3", 4: "md:columns-2 lg:columns-3 xl:columns-4" };
|
|
3183
|
+
var gapClasses4 = { sm: "gap-3", md: "gap-5", lg: "gap-8" };
|
|
3184
|
+
function MasonryGrid({ children, columns = 3, gap = "md", className = "", style }) {
|
|
3185
|
+
return /* @__PURE__ */ jsx102("div", { className: [columnClasses[columns], gapClasses4[gap], className].filter(Boolean).join(" "), style, children });
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
// src/components/layout/PageRail.tsx
|
|
3189
|
+
import { Fragment as Fragment4, jsx as jsx103, jsxs as jsxs79 } from "react/jsx-runtime";
|
|
3190
|
+
function PageRail({ title, items, actions, className = "", style }) {
|
|
3191
|
+
return /* @__PURE__ */ jsxs79("aside", { className: ["sticky top-20 rounded-none border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-3 shadow-[var(--tapiz-shadow-sm)]", className].filter(Boolean).join(" "), style, children: [
|
|
3192
|
+
title ? /* @__PURE__ */ jsx103("div", { className: "kicker mb-3 px-2", children: title }) : null,
|
|
3193
|
+
/* @__PURE__ */ jsx103("nav", { className: "flex flex-col gap-1", children: items.map((item, index) => {
|
|
3194
|
+
const content = /* @__PURE__ */ jsxs79(Fragment4, { children: [
|
|
3195
|
+
/* @__PURE__ */ jsx103("span", { className: "truncate", children: item.label }),
|
|
3196
|
+
item.meta ? /* @__PURE__ */ jsx103("span", { className: "font-mono text-[10px] text-[var(--tapiz-text-muted)]", children: item.meta }) : null
|
|
3197
|
+
] });
|
|
3198
|
+
const classes = ["flex items-center justify-between gap-3 border px-3 py-2 text-sm transition", item.active ? "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)] text-[var(--tapiz-text-primary)]" : "border-transparent text-[var(--tapiz-text-muted)] hover:border-[var(--tapiz-border-subtle)] hover:text-[var(--tapiz-text-primary)]"].join(" ");
|
|
3199
|
+
return item.href ? /* @__PURE__ */ jsx103("a", { href: item.href, className: classes, children: content }, index) : /* @__PURE__ */ jsx103("div", { className: classes, children: content }, index);
|
|
3200
|
+
}) }),
|
|
3201
|
+
actions ? /* @__PURE__ */ jsx103("div", { className: "mt-3 border-t border-[var(--tapiz-border-subtle)] pt-3", children: actions }) : null
|
|
3202
|
+
] });
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
// src/components/layout/StickyBar.tsx
|
|
3206
|
+
import { jsx as jsx104 } from "react/jsx-runtime";
|
|
3207
|
+
function StickyBar({ children, position = "top", className = "", style }) {
|
|
3208
|
+
return /* @__PURE__ */ jsx104(
|
|
3209
|
+
"div",
|
|
3210
|
+
{
|
|
3211
|
+
className: ["z-30 border-[var(--tapiz-border-subtle)] bg-[color-mix(in_srgb,var(--tapiz-bg-canvas)_88%,transparent)] px-4 py-3 backdrop-blur-xl", position === "top" ? "sticky top-0 border-b" : "sticky bottom-0 border-t", className].filter(Boolean).join(" "),
|
|
3212
|
+
style,
|
|
3213
|
+
children
|
|
3214
|
+
}
|
|
3215
|
+
);
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
// src/components/forms/Combobox.tsx
|
|
3219
|
+
import { jsx as jsx105, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
3220
|
+
function Combobox({ options, placeholder = "Select option", invalid = false, className = "", ...props }) {
|
|
3221
|
+
return /* @__PURE__ */ jsxs80("select", { ...props, className: ["input-field appearance-none bg-[var(--tapiz-bg-surface)]", invalid ? "border-warn focus:border-warn" : "", className].filter(Boolean).join(" "), children: [
|
|
3222
|
+
/* @__PURE__ */ jsx105("option", { value: "", children: placeholder }),
|
|
3223
|
+
options.map((option) => /* @__PURE__ */ jsx105("option", { value: option.value, children: String(option.label) }, option.value))
|
|
3224
|
+
] });
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
// src/components/forms/DateRangePicker.tsx
|
|
3228
|
+
import { jsx as jsx106, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
3229
|
+
function DateRangePicker({ startLabel = "From", endLabel = "To", startProps, endProps, className = "" }) {
|
|
3230
|
+
return /* @__PURE__ */ jsxs81("div", { className: ["grid gap-3 md:grid-cols-2", className].filter(Boolean).join(" "), children: [
|
|
3231
|
+
/* @__PURE__ */ jsxs81("label", { className: "flex flex-col gap-1.5 text-sm text-[var(--tapiz-text-muted)]", children: [
|
|
3232
|
+
/* @__PURE__ */ jsx106("span", { children: startLabel }),
|
|
3233
|
+
/* @__PURE__ */ jsx106("input", { type: "date", ...startProps, className: ["input-field", startProps?.className || ""].join(" ") })
|
|
3234
|
+
] }),
|
|
3235
|
+
/* @__PURE__ */ jsxs81("label", { className: "flex flex-col gap-1.5 text-sm text-[var(--tapiz-text-muted)]", children: [
|
|
3236
|
+
/* @__PURE__ */ jsx106("span", { children: endLabel }),
|
|
3237
|
+
/* @__PURE__ */ jsx106("input", { type: "date", ...endProps, className: ["input-field", endProps?.className || ""].join(" ") })
|
|
3238
|
+
] })
|
|
3239
|
+
] });
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3242
|
+
// src/components/forms/ColorSwatchPicker.tsx
|
|
3243
|
+
import { jsx as jsx107, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
3244
|
+
function ColorSwatchPicker({ options, value, onChange, className = "" }) {
|
|
3245
|
+
return /* @__PURE__ */ jsx107("div", { className: ["flex flex-wrap gap-2", className].filter(Boolean).join(" "), children: options.map((option) => {
|
|
3246
|
+
const selected = option.value === value;
|
|
3247
|
+
return /* @__PURE__ */ jsxs82("button", { type: "button", "aria-pressed": selected, onClick: () => onChange?.(option.value), className: ["flex items-center gap-2 border px-3 py-2 text-sm transition", selected ? "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)]" : "border-[var(--tapiz-border-subtle)] hover:border-[var(--tapiz-border-strong)]"].join(" "), children: [
|
|
3248
|
+
/* @__PURE__ */ jsx107("span", { className: "h-4 w-4 border border-[var(--tapiz-border-strong)]", style: { background: option.color } }),
|
|
3249
|
+
/* @__PURE__ */ jsx107("span", { children: option.label })
|
|
3250
|
+
] }, option.value);
|
|
3251
|
+
}) });
|
|
3252
|
+
}
|
|
3253
|
+
|
|
3254
|
+
// src/components/forms/RatingInput.tsx
|
|
3255
|
+
import { jsx as jsx108 } from "react/jsx-runtime";
|
|
3256
|
+
function RatingInput({ value = 0, max = 5, icon = "\u2605", onChange, label = "Rating", className = "" }) {
|
|
3257
|
+
return /* @__PURE__ */ jsx108("div", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), role: "radiogroup", "aria-label": label, children: Array.from({ length: max }, (_, index) => {
|
|
3258
|
+
const score = index + 1;
|
|
3259
|
+
const active = score <= value;
|
|
3260
|
+
return /* @__PURE__ */ jsx108("button", { type: "button", role: "radio", "aria-checked": active, onClick: () => onChange?.(score), className: ["grid h-9 w-9 place-items-center border text-base transition", active ? "border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)] text-[var(--tapiz-accent)]" : "border-[var(--tapiz-border-subtle)] text-[var(--tapiz-text-muted)] hover:border-[var(--tapiz-border-strong)]"].join(" "), children: icon }, score);
|
|
3261
|
+
}) });
|
|
3262
|
+
}
|
|
3263
|
+
|
|
3264
|
+
// src/components/data-display/ScoreRing.tsx
|
|
3265
|
+
import { jsx as jsx109, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
3266
|
+
function ScoreRing({ value, max = 100, label, size = 112, className = "" }) {
|
|
3267
|
+
const normalized = Math.max(0, Math.min(1, value / max));
|
|
3268
|
+
const radius = 42;
|
|
3269
|
+
const circumference = 2 * Math.PI * radius;
|
|
3270
|
+
const dash = circumference * normalized;
|
|
3271
|
+
return /* @__PURE__ */ jsxs83("div", { className: ["inline-grid place-items-center", className].filter(Boolean).join(" "), style: { width: size, height: size }, children: [
|
|
3272
|
+
/* @__PURE__ */ jsxs83("svg", { viewBox: "0 0 100 100", className: "h-full w-full -rotate-90", children: [
|
|
3273
|
+
/* @__PURE__ */ jsx109("circle", { cx: "50", cy: "50", r: radius, fill: "none", stroke: "var(--tapiz-border-subtle)", strokeWidth: "10" }),
|
|
3274
|
+
/* @__PURE__ */ jsx109("circle", { cx: "50", cy: "50", r: radius, fill: "none", stroke: "var(--tapiz-accent)", strokeWidth: "10", strokeLinecap: "square", strokeDasharray: `${dash} ${circumference - dash}` })
|
|
3275
|
+
] }),
|
|
3276
|
+
/* @__PURE__ */ jsxs83("div", { className: "absolute text-center", children: [
|
|
3277
|
+
/* @__PURE__ */ jsxs83("div", { className: "font-display text-2xl font-semibold text-[var(--tapiz-text-primary)]", children: [
|
|
3278
|
+
Math.round(normalized * 100),
|
|
3279
|
+
"%"
|
|
3280
|
+
] }),
|
|
3281
|
+
label ? /* @__PURE__ */ jsx109("div", { className: "font-mono text-[10px] uppercase tracking-[0.16em] text-[var(--tapiz-text-muted)]", children: label }) : null
|
|
3282
|
+
] })
|
|
3283
|
+
] });
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
// src/components/data-display/HeatmapGrid.tsx
|
|
3287
|
+
import { jsx as jsx110 } from "react/jsx-runtime";
|
|
3288
|
+
function HeatmapGrid({ cells, columns = 7, max, className = "" }) {
|
|
3289
|
+
const peak = max ?? Math.max(1, ...cells.map((cell) => cell.value));
|
|
3290
|
+
return /* @__PURE__ */ jsx110("div", { className: ["grid gap-1", className].filter(Boolean).join(" "), style: { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }, children: cells.map((cell, index) => {
|
|
3291
|
+
const opacity = 0.15 + Math.min(1, cell.value / peak) * 0.75;
|
|
3292
|
+
return /* @__PURE__ */ jsx110("div", { title: cell.title, className: "aspect-square border border-[var(--tapiz-border-subtle)]", style: { background: `color-mix(in srgb, var(--tapiz-accent) ${Math.round(opacity * 100)}%, transparent)` }, children: cell.label ? /* @__PURE__ */ jsx110("span", { className: "sr-only", children: cell.label }) : null }, index);
|
|
3293
|
+
}) });
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3296
|
+
// src/components/data-display/FunnelChart.tsx
|
|
3297
|
+
import { jsx as jsx111, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
3298
|
+
function FunnelChart({ steps, className = "" }) {
|
|
3299
|
+
const max = Math.max(1, ...steps.map((step) => step.value));
|
|
3300
|
+
return /* @__PURE__ */ jsx111("div", { className: ["space-y-3", className].filter(Boolean).join(" "), children: steps.map((step, index) => {
|
|
3301
|
+
const width = Math.max(8, step.value / max * 100);
|
|
3302
|
+
return /* @__PURE__ */ jsxs84("div", { children: [
|
|
3303
|
+
/* @__PURE__ */ jsxs84("div", { className: "mb-1 flex items-center justify-between gap-3 text-sm", children: [
|
|
3304
|
+
/* @__PURE__ */ jsx111("span", { className: "font-medium text-[var(--tapiz-text-primary)]", children: step.label }),
|
|
3305
|
+
/* @__PURE__ */ jsxs84("span", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: [
|
|
3306
|
+
step.value,
|
|
3307
|
+
step.meta ? ` \xB7 ${String(step.meta)}` : ""
|
|
3308
|
+
] })
|
|
3309
|
+
] }),
|
|
3310
|
+
/* @__PURE__ */ jsx111("div", { className: "h-9 border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)]", children: /* @__PURE__ */ jsx111("div", { className: "h-full border-r border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)]", style: { width: `${width}%` } }) })
|
|
3311
|
+
] }, index);
|
|
3312
|
+
}) });
|
|
3313
|
+
}
|
|
3314
|
+
|
|
3315
|
+
// src/components/data-display/ComparisonMeter.tsx
|
|
3316
|
+
import { jsx as jsx112, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
3317
|
+
function ComparisonMeter({ leftLabel, rightLabel, value, className = "" }) {
|
|
3318
|
+
const clamped = Math.max(0, Math.min(100, value));
|
|
3319
|
+
return /* @__PURE__ */ jsxs85("div", { className, children: [
|
|
3320
|
+
/* @__PURE__ */ jsxs85("div", { className: "mb-2 flex justify-between gap-3 text-sm text-[var(--tapiz-text-muted)]", children: [
|
|
3321
|
+
/* @__PURE__ */ jsx112("span", { children: leftLabel }),
|
|
3322
|
+
/* @__PURE__ */ jsx112("span", { children: rightLabel })
|
|
3323
|
+
] }),
|
|
3324
|
+
/* @__PURE__ */ jsxs85("div", { className: "relative h-3 border border-[var(--tapiz-border-strong)] bg-[var(--tapiz-bg-surface-muted)]", children: [
|
|
3325
|
+
/* @__PURE__ */ jsx112("div", { className: "h-full bg-[var(--tapiz-accent)]", style: { width: `${clamped}%` } }),
|
|
3326
|
+
/* @__PURE__ */ jsx112("div", { className: "absolute top-[-6px] h-6 w-px bg-[var(--tapiz-border-strong)]", style: { left: `${clamped}%` } })
|
|
3327
|
+
] })
|
|
3328
|
+
] });
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3331
|
+
// src/components/framework/ActivityFeed.tsx
|
|
3332
|
+
import { jsx as jsx113, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
3333
|
+
function ActivityFeed({ items, className = "" }) {
|
|
3334
|
+
return /* @__PURE__ */ jsx113("div", { className: ["divide-y divide-[var(--tapiz-border-subtle)] border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)]", className].filter(Boolean).join(" "), children: items.map((item, index) => /* @__PURE__ */ jsxs86("div", { className: "flex gap-3 p-4", children: [
|
|
3335
|
+
/* @__PURE__ */ jsx113(Avatar, { name: item.actor, src: item.avatarUrl, size: "sm" }),
|
|
3336
|
+
/* @__PURE__ */ jsxs86("div", { className: "min-w-0 flex-1", children: [
|
|
3337
|
+
/* @__PURE__ */ jsxs86("p", { className: "text-sm text-[var(--tapiz-text-primary)]", children: [
|
|
3338
|
+
/* @__PURE__ */ jsx113("strong", { children: item.actor }),
|
|
3339
|
+
" ",
|
|
3340
|
+
item.action
|
|
3341
|
+
] }),
|
|
3342
|
+
item.meta ? /* @__PURE__ */ jsx113("div", { className: "mt-1 text-sm text-[var(--tapiz-text-muted)]", children: item.meta }) : null
|
|
3343
|
+
] }),
|
|
3344
|
+
item.time ? /* @__PURE__ */ jsx113("div", { className: "font-mono text-[10px] uppercase tracking-[0.14em] text-[var(--tapiz-text-muted)]", children: item.time }) : null
|
|
3345
|
+
] }, index)) });
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
// src/components/framework/InboxList.tsx
|
|
3349
|
+
import { jsx as jsx114, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
3350
|
+
function InboxList({ items, className = "" }) {
|
|
3351
|
+
return /* @__PURE__ */ jsx114("div", { className: ["divide-y divide-[var(--tapiz-border-subtle)] border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)]", className].filter(Boolean).join(" "), children: items.map((item, index) => /* @__PURE__ */ jsxs87("article", { className: ["p-4 transition hover:bg-[var(--tapiz-bg-surface-muted)]", item.unread ? "border-l-4 border-l-[var(--tapiz-accent)]" : ""].join(" "), children: [
|
|
3352
|
+
/* @__PURE__ */ jsxs87("div", { className: "flex items-start justify-between gap-3", children: [
|
|
3353
|
+
/* @__PURE__ */ jsxs87("div", { className: "min-w-0", children: [
|
|
3354
|
+
/* @__PURE__ */ jsx114("h3", { className: "truncate text-sm font-semibold text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
3355
|
+
item.sender ? /* @__PURE__ */ jsx114("p", { className: "mt-1 text-xs text-[var(--tapiz-text-muted)]", children: item.sender }) : null
|
|
3356
|
+
] }),
|
|
3357
|
+
/* @__PURE__ */ jsxs87("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
3358
|
+
item.tag ? /* @__PURE__ */ jsx114(Badge, { children: item.tag }) : null,
|
|
3359
|
+
item.time ? /* @__PURE__ */ jsx114("span", { className: "font-mono text-[10px] text-[var(--tapiz-text-muted)]", children: item.time }) : null
|
|
3360
|
+
] })
|
|
3361
|
+
] }),
|
|
3362
|
+
item.snippet ? /* @__PURE__ */ jsx114("p", { className: "mt-2 line-clamp-2 text-sm text-[var(--tapiz-text-muted)]", children: item.snippet }) : null
|
|
3363
|
+
] }, index)) });
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
// src/components/framework/ApprovalQueue.tsx
|
|
3367
|
+
import { jsx as jsx115, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
3368
|
+
function ApprovalQueue({ items, onApprove, onReject, className = "" }) {
|
|
3369
|
+
return /* @__PURE__ */ jsx115("div", { className: ["space-y-3", className].filter(Boolean).join(" "), children: items.map((item, index) => /* @__PURE__ */ jsx115("article", { className: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-4", children: /* @__PURE__ */ jsxs88("div", { className: "flex flex-col gap-4 md:flex-row md:items-start md:justify-between", children: [
|
|
3370
|
+
/* @__PURE__ */ jsxs88("div", { children: [
|
|
3371
|
+
/* @__PURE__ */ jsxs88("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
3372
|
+
/* @__PURE__ */ jsx115("h3", { className: "font-semibold text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
3373
|
+
item.priority ? /* @__PURE__ */ jsx115(Badge, { variant: item.priority === "high" ? "danger" : item.priority === "medium" ? "warning" : "default", children: item.priority }) : null
|
|
3374
|
+
] }),
|
|
3375
|
+
item.requester ? /* @__PURE__ */ jsxs88("p", { className: "mt-1 text-xs text-[var(--tapiz-text-muted)]", children: [
|
|
3376
|
+
"Requested by ",
|
|
3377
|
+
item.requester
|
|
3378
|
+
] }) : null,
|
|
3379
|
+
item.description ? /* @__PURE__ */ jsx115("p", { className: "mt-2 text-sm text-[var(--tapiz-text-muted)]", children: item.description }) : null
|
|
3380
|
+
] }),
|
|
3381
|
+
/* @__PURE__ */ jsxs88("div", { className: "flex gap-2", children: [
|
|
3382
|
+
/* @__PURE__ */ jsx115(Button, { size: "sm", variant: "secondary", onClick: () => onReject?.(index), children: "Reject" }),
|
|
3383
|
+
/* @__PURE__ */ jsx115(Button, { size: "sm", onClick: () => onApprove?.(index), children: "Approve" })
|
|
3384
|
+
] })
|
|
3385
|
+
] }) }, index)) });
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
// src/components/framework/SLAStatus.tsx
|
|
3389
|
+
import { jsx as jsx116, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
3390
|
+
function SLAStatus({ label, value, target = 95, className = "" }) {
|
|
3391
|
+
const ok = value >= target;
|
|
3392
|
+
return /* @__PURE__ */ jsxs89("div", { className: ["border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-4", className].filter(Boolean).join(" "), children: [
|
|
3393
|
+
/* @__PURE__ */ jsxs89("div", { className: "flex items-center justify-between gap-3", children: [
|
|
3394
|
+
/* @__PURE__ */ jsx116("span", { className: "text-sm font-medium text-[var(--tapiz-text-primary)]", children: label }),
|
|
3395
|
+
/* @__PURE__ */ jsx116("span", { className: ["font-mono text-xs", ok ? "text-[var(--tapiz-success)]" : "text-[var(--tapiz-warning)]"].join(" "), children: ok ? "Within SLA" : "At risk" })
|
|
3396
|
+
] }),
|
|
3397
|
+
/* @__PURE__ */ jsx116("div", { className: "mt-3 h-2 border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)]", children: /* @__PURE__ */ jsx116("div", { className: "h-full bg-[var(--tapiz-accent)]", style: { width: `${Math.max(0, Math.min(100, value))}%` } }) }),
|
|
3398
|
+
/* @__PURE__ */ jsxs89("div", { className: "mt-2 flex justify-between font-mono text-[10px] uppercase tracking-[0.14em] text-[var(--tapiz-text-muted)]", children: [
|
|
3399
|
+
/* @__PURE__ */ jsxs89("span", { children: [
|
|
3400
|
+
value,
|
|
3401
|
+
"%"
|
|
3402
|
+
] }),
|
|
3403
|
+
/* @__PURE__ */ jsxs89("span", { children: [
|
|
3404
|
+
"Target ",
|
|
3405
|
+
target,
|
|
3406
|
+
"%"
|
|
3407
|
+
] })
|
|
3408
|
+
] })
|
|
3409
|
+
] });
|
|
3410
|
+
}
|
|
3411
|
+
|
|
3412
|
+
// src/components/framework/FeatureFlagTable.tsx
|
|
3413
|
+
import { jsx as jsx117, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
3414
|
+
function FeatureFlagTable({ flags, onToggle, className = "" }) {
|
|
3415
|
+
return /* @__PURE__ */ jsx117("div", { className: ["overflow-hidden border border-[var(--tapiz-border-subtle)]", className].filter(Boolean).join(" "), children: flags.map((flag) => /* @__PURE__ */ jsxs90("div", { className: "grid gap-3 border-b border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-4 last:border-b-0 md:grid-cols-[1fr_auto_auto] md:items-center", children: [
|
|
3416
|
+
/* @__PURE__ */ jsxs90("div", { children: [
|
|
3417
|
+
/* @__PURE__ */ jsxs90("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
3418
|
+
/* @__PURE__ */ jsx117("h3", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: flag.name }),
|
|
3419
|
+
/* @__PURE__ */ jsx117(Badge, { children: flag.key })
|
|
3420
|
+
] }),
|
|
3421
|
+
flag.description ? /* @__PURE__ */ jsx117("p", { className: "mt-1 text-sm text-[var(--tapiz-text-muted)]", children: flag.description }) : null
|
|
3422
|
+
] }),
|
|
3423
|
+
/* @__PURE__ */ jsx117("div", { className: "text-sm text-[var(--tapiz-text-muted)]", children: flag.rollout }),
|
|
3424
|
+
/* @__PURE__ */ jsx117(Switch, { checked: flag.enabled, onChange: (checked) => onToggle?.(flag.key, checked) })
|
|
3425
|
+
] }, flag.key)) });
|
|
3426
|
+
}
|
|
3427
|
+
|
|
3428
|
+
// src/components/framework/PlanUsage.tsx
|
|
3429
|
+
import { jsx as jsx118, jsxs as jsxs91 } from "react/jsx-runtime";
|
|
3430
|
+
function PlanUsage({ title = "Plan usage", items, className = "" }) {
|
|
3431
|
+
return /* @__PURE__ */ jsxs91("section", { className: ["border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-5", className].filter(Boolean).join(" "), children: [
|
|
3432
|
+
/* @__PURE__ */ jsx118("h3", { className: "text-sm font-semibold text-[var(--tapiz-text-primary)]", children: title }),
|
|
3433
|
+
/* @__PURE__ */ jsx118("div", { className: "mt-4 space-y-4", children: items.map((item, index) => {
|
|
3434
|
+
const pct = item.limit ? Math.min(100, item.used / item.limit * 100) : 0;
|
|
3435
|
+
return /* @__PURE__ */ jsxs91("div", { children: [
|
|
3436
|
+
/* @__PURE__ */ jsxs91("div", { className: "mb-1 flex justify-between text-sm", children: [
|
|
3437
|
+
/* @__PURE__ */ jsx118("span", { className: "text-[var(--tapiz-text-primary)]", children: item.label }),
|
|
3438
|
+
/* @__PURE__ */ jsxs91("span", { className: "font-mono text-xs text-[var(--tapiz-text-muted)]", children: [
|
|
3439
|
+
item.used,
|
|
3440
|
+
"/",
|
|
3441
|
+
item.limit
|
|
3442
|
+
] })
|
|
3443
|
+
] }),
|
|
3444
|
+
/* @__PURE__ */ jsx118("div", { className: "h-2 border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)]", children: /* @__PURE__ */ jsx118("div", { className: "h-full bg-[var(--tapiz-accent)]", style: { width: `${pct}%` } }) })
|
|
3445
|
+
] }, index);
|
|
3446
|
+
}) })
|
|
3447
|
+
] });
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
// src/components/marketing/AnnouncementBar.tsx
|
|
3451
|
+
import { jsx as jsx119, jsxs as jsxs92 } from "react/jsx-runtime";
|
|
3452
|
+
function AnnouncementBar({ children, action, className = "" }) {
|
|
3453
|
+
return /* @__PURE__ */ jsx119("div", { className: ["border-b border-[var(--tapiz-border-strong)] bg-[var(--tapiz-accent-soft)] px-4 py-3 text-sm text-[var(--tapiz-text-primary)]", className].filter(Boolean).join(" "), children: /* @__PURE__ */ jsxs92("div", { className: "mx-auto flex max-w-7xl flex-wrap items-center justify-center gap-3 text-center", children: [
|
|
3454
|
+
" ",
|
|
3455
|
+
/* @__PURE__ */ jsx119("span", { children }),
|
|
3456
|
+
action ? /* @__PURE__ */ jsx119("span", { children: action }) : null
|
|
3457
|
+
] }) });
|
|
3458
|
+
}
|
|
3459
|
+
|
|
3460
|
+
// src/components/marketing/FAQSection.tsx
|
|
3461
|
+
import { jsx as jsx120, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
3462
|
+
function FAQSection({ title = "Frequently asked questions", description, items, className = "" }) {
|
|
3463
|
+
return /* @__PURE__ */ jsxs93("section", { className, children: [
|
|
3464
|
+
/* @__PURE__ */ jsxs93("div", { className: "mb-6 max-w-2xl", children: [
|
|
3465
|
+
/* @__PURE__ */ jsx120("div", { className: "kicker", children: "FAQ" }),
|
|
3466
|
+
/* @__PURE__ */ jsx120("h2", { className: "mt-2 text-3xl font-semibold tracking-[-0.05em] text-[var(--tapiz-text-primary)]", children: title }),
|
|
3467
|
+
description ? /* @__PURE__ */ jsx120("p", { className: "mt-2 text-sm leading-6 text-[var(--tapiz-text-muted)]", children: description }) : null
|
|
3468
|
+
] }),
|
|
3469
|
+
/* @__PURE__ */ jsx120(Accordion, { items: items.map((item, index) => ({ id: `faq-${index}`, title: item.question, content: item.answer })) })
|
|
3470
|
+
] });
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
// src/components/marketing/RoadmapList.tsx
|
|
3474
|
+
import { jsx as jsx121, jsxs as jsxs94 } from "react/jsx-runtime";
|
|
3475
|
+
function RoadmapList({ items, className = "" }) {
|
|
3476
|
+
return /* @__PURE__ */ jsx121("div", { className: ["grid gap-3 md:grid-cols-3", className].filter(Boolean).join(" "), children: items.map((item, index) => /* @__PURE__ */ jsxs94("article", { className: "border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface)] p-5", children: [
|
|
3477
|
+
/* @__PURE__ */ jsxs94("div", { className: "flex items-center justify-between gap-3", children: [
|
|
3478
|
+
/* @__PURE__ */ jsx121("span", { className: "kicker", children: item.quarter ?? `0${index + 1}` }),
|
|
3479
|
+
item.status ? /* @__PURE__ */ jsx121(Badge, { children: item.status }) : null
|
|
3480
|
+
] }),
|
|
3481
|
+
/* @__PURE__ */ jsx121("h3", { className: "mt-4 font-semibold text-[var(--tapiz-text-primary)]", children: item.title }),
|
|
3482
|
+
item.description ? /* @__PURE__ */ jsx121("p", { className: "mt-2 text-sm leading-6 text-[var(--tapiz-text-muted)]", children: item.description }) : null
|
|
3483
|
+
] }, index)) });
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
// src/components/feedback/InlineStatus.tsx
|
|
3487
|
+
import { jsx as jsx122, jsxs as jsxs95 } from "react/jsx-runtime";
|
|
3488
|
+
var toneClasses5 = {
|
|
3489
|
+
neutral: "bg-[var(--tapiz-text-muted)]",
|
|
3490
|
+
success: "bg-[var(--tapiz-success)]",
|
|
3491
|
+
warning: "bg-[var(--tapiz-warning)]",
|
|
3492
|
+
danger: "bg-[var(--tapiz-danger)]",
|
|
3493
|
+
info: "bg-[var(--tapiz-info)]"
|
|
3494
|
+
};
|
|
3495
|
+
function InlineStatus({ tone: tone2 = "neutral", children, pulse = false, className = "" }) {
|
|
3496
|
+
return /* @__PURE__ */ jsxs95("span", { className: ["inline-flex items-center gap-2 text-sm text-[var(--tapiz-text-muted)]", className].filter(Boolean).join(" "), children: [
|
|
3497
|
+
/* @__PURE__ */ jsx122("span", { className: ["h-2 w-2 rounded-full", toneClasses5[tone2], pulse ? "animate-pulse" : ""].filter(Boolean).join(" ") }),
|
|
3498
|
+
children
|
|
3499
|
+
] });
|
|
3500
|
+
}
|
|
3501
|
+
|
|
3502
|
+
// src/showcase/TapizDocsPage.tsx
|
|
3503
|
+
import { Fragment as Fragment5, jsx as jsx123, jsxs as jsxs96 } from "react/jsx-runtime";
|
|
3504
|
+
var demoRows = [
|
|
3505
|
+
{ id: "1", student: "Mila Petrovi\u0107", status: "Active", score: 94 },
|
|
3506
|
+
{ id: "2", student: "Vuk Jovanovi\u0107", status: "Pending", score: 82 },
|
|
3507
|
+
{ id: "3", student: "Sara Ili\u0107", status: "Blocked", score: 68 }
|
|
3508
|
+
];
|
|
3509
|
+
var calendarDays = Array.from({ length: 35 }, (_, index) => ({
|
|
3510
|
+
date: index + 1,
|
|
3511
|
+
selected: index === 10,
|
|
3512
|
+
muted: index > 30,
|
|
3513
|
+
events: index === 10 ? ["Exam review", "Parent sync"] : index === 15 ? ["Quiz"] : void 0
|
|
3514
|
+
}));
|
|
3515
|
+
function DemoSection({ id, title, description, children }) {
|
|
3516
|
+
return /* @__PURE__ */ jsxs96("section", { id, className: "scroll-mt-20 border-t border-[var(--tapiz-border-subtle)] py-12", children: [
|
|
3517
|
+
/* @__PURE__ */ jsxs96("div", { className: "mb-6 flex flex-col gap-2 md:flex-row md:items-end md:justify-between", children: [
|
|
3518
|
+
/* @__PURE__ */ jsxs96("div", { children: [
|
|
3519
|
+
/* @__PURE__ */ jsx123("div", { className: "kicker", children: id }),
|
|
3520
|
+
/* @__PURE__ */ jsx123("h2", { className: "mt-2 text-3xl font-semibold tracking-[-0.05em] text-[var(--tapiz-text-primary)]", children: title }),
|
|
3521
|
+
/* @__PURE__ */ jsx123("p", { className: "mt-2 max-w-2xl text-sm leading-6 text-[var(--tapiz-text-muted)]", children: description })
|
|
3522
|
+
] }),
|
|
3523
|
+
/* @__PURE__ */ jsx123("a", { href: "#top", className: "font-mono text-xs uppercase tracking-[0.16em] text-[var(--tapiz-accent)]", children: "Back to top" })
|
|
3524
|
+
] }),
|
|
3525
|
+
children
|
|
3526
|
+
] });
|
|
3527
|
+
}
|
|
3528
|
+
function TapizDocsPage({ title = "Tapiz UI Framework", subtitle = "A brutal-enterprise React component system with tokens, primitives, patterns, and ready-made application blocks." }) {
|
|
3529
|
+
return /* @__PURE__ */ jsxs96("main", { id: "top", className: "tapiz-enterprise-shell min-h-screen tapiz-noise-bg", children: [
|
|
3530
|
+
/* @__PURE__ */ jsx123(
|
|
3531
|
+
TopNav,
|
|
3532
|
+
{
|
|
3533
|
+
brand: /* @__PURE__ */ jsx123("span", { className: "font-display text-lg font-semibold tracking-[-0.04em]", children: "Tapiz UI" }),
|
|
3534
|
+
links: [
|
|
3535
|
+
{ label: "Foundations", href: "#foundations" },
|
|
3536
|
+
{ label: "Forms", href: "#forms" },
|
|
3537
|
+
{ label: "Data", href: "#data" },
|
|
3538
|
+
{ label: "Framework", href: "#framework" },
|
|
3539
|
+
{ label: "Advanced", href: "#advanced" },
|
|
3540
|
+
{ label: "Marketing", href: "#marketing" }
|
|
3541
|
+
],
|
|
3542
|
+
actions: /* @__PURE__ */ jsx123(Button, { size: "sm", variant: "brutal", children: "Install" })
|
|
3543
|
+
}
|
|
3544
|
+
),
|
|
3545
|
+
/* @__PURE__ */ jsx123(
|
|
3546
|
+
HeroFrame,
|
|
3547
|
+
{
|
|
3548
|
+
eyebrow: "Design system / React framework",
|
|
3549
|
+
title,
|
|
3550
|
+
description: subtitle,
|
|
3551
|
+
actions: /* @__PURE__ */ jsxs96(Fragment5, { children: [
|
|
3552
|
+
/* @__PURE__ */ jsx123(Button, { variant: "primary", children: "Start building" }),
|
|
3553
|
+
/* @__PURE__ */ jsx123(Button, { variant: "secondary", children: "View tokens" })
|
|
3554
|
+
] }),
|
|
3555
|
+
meta: "Light/dark safe \xB7 token driven \xB7 no app-specific dependencies",
|
|
3556
|
+
visual: /* @__PURE__ */ jsxs96(MockupFrame, { title: "Component registry", children: [
|
|
3557
|
+
/* @__PURE__ */ jsxs96(StatGrid, { children: [
|
|
3558
|
+
/* @__PURE__ */ jsx123(MetricCard, { label: "Components", value: "80+", trend: "expanded", trendTone: "positive" }),
|
|
3559
|
+
/* @__PURE__ */ jsx123(MetricCard, { label: "Themes", value: "2", trend: "light/dark" }),
|
|
3560
|
+
/* @__PURE__ */ jsx123(MetricCard, { label: "Patterns", value: "12", trend: "framework", trendTone: "warning" })
|
|
3561
|
+
] }),
|
|
3562
|
+
/* @__PURE__ */ jsx123("div", { className: "mt-4", children: /* @__PURE__ */ jsx123(Sparkline, { values: [18, 24, 21, 32, 44, 39, 58], width: 420, height: 56 }) })
|
|
3563
|
+
] })
|
|
3564
|
+
}
|
|
3565
|
+
),
|
|
3566
|
+
/* @__PURE__ */ jsxs96(Container, { size: "xl", className: "pb-16", children: [
|
|
3567
|
+
/* @__PURE__ */ jsx123(Surface, { variant: "brutal", padding: "md", className: "mb-8", children: /* @__PURE__ */ jsxs96(Cluster, { justify: "between", align: "center", children: [
|
|
3568
|
+
/* @__PURE__ */ jsx123(Breadcrumbs, { items: [{ label: "Docs", href: "#top" }, { label: "Components" }] }),
|
|
3569
|
+
/* @__PURE__ */ jsxs96(Cluster, { gap: "sm", children: [
|
|
3570
|
+
/* @__PURE__ */ jsx123(Kbd, { children: "\u2318" }),
|
|
3571
|
+
/* @__PURE__ */ jsx123(Kbd, { children: "K" }),
|
|
3572
|
+
/* @__PURE__ */ jsx123("span", { className: "text-sm text-[var(--tapiz-text-muted)]", children: "Command-first framework UX" })
|
|
3573
|
+
] })
|
|
3574
|
+
] }) }),
|
|
3575
|
+
/* @__PURE__ */ jsxs96(DemoSection, { id: "foundations", title: "Foundations", description: "Core surfaces, cards, badges, layout helpers, empty states, skeletons and typography primitives.", children: [
|
|
3576
|
+
/* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "16rem", children: [
|
|
3577
|
+
/* @__PURE__ */ jsxs96(Card, { variant: "surface", children: [
|
|
3578
|
+
/* @__PURE__ */ jsx123("div", { className: "kicker", children: "surface" }),
|
|
3579
|
+
/* @__PURE__ */ jsx123("p", { className: "mt-2 text-sm text-[var(--tapiz-text-muted)]", children: "Default card treatment." })
|
|
3580
|
+
] }),
|
|
3581
|
+
/* @__PURE__ */ jsxs96(Card, { variant: "raised", children: [
|
|
3582
|
+
/* @__PURE__ */ jsx123("div", { className: "kicker", children: "raised" }),
|
|
3583
|
+
/* @__PURE__ */ jsx123("p", { className: "mt-2 text-sm text-[var(--tapiz-text-muted)]", children: "Elevated enterprise panel." })
|
|
3584
|
+
] }),
|
|
3585
|
+
/* @__PURE__ */ jsxs96(Card, { variant: "brutal", children: [
|
|
3586
|
+
/* @__PURE__ */ jsx123("div", { className: "kicker", children: "brutal" }),
|
|
3587
|
+
/* @__PURE__ */ jsx123("p", { className: "mt-2 text-sm text-[var(--tapiz-text-muted)]", children: "Hard border + hard shadow." })
|
|
3588
|
+
] }),
|
|
3589
|
+
/* @__PURE__ */ jsxs96(Card, { variant: "glass", children: [
|
|
3590
|
+
/* @__PURE__ */ jsx123("div", { className: "kicker", children: "glass" }),
|
|
3591
|
+
/* @__PURE__ */ jsx123("p", { className: "mt-2 text-sm text-[var(--tapiz-text-muted)]", children: "Backdrop style surface." })
|
|
3592
|
+
] })
|
|
3593
|
+
] }),
|
|
3594
|
+
/* @__PURE__ */ jsx123(Divider, { label: "status tokens", className: "my-8" }),
|
|
3595
|
+
/* @__PURE__ */ jsxs96(Cluster, { children: [
|
|
3596
|
+
/* @__PURE__ */ jsx123(Badge, { children: "Default" }),
|
|
3597
|
+
/* @__PURE__ */ jsx123(Badge, { variant: "success", children: "Success" }),
|
|
3598
|
+
/* @__PURE__ */ jsx123(Badge, { variant: "warning", children: "Warning" }),
|
|
3599
|
+
/* @__PURE__ */ jsx123(Badge, { variant: "danger", children: "Danger" }),
|
|
3600
|
+
/* @__PURE__ */ jsx123(Badge, { variant: "info", children: "Info" }),
|
|
3601
|
+
/* @__PURE__ */ jsx123(StatusBadge, { label: "Active", variant: "active" }),
|
|
3602
|
+
/* @__PURE__ */ jsx123(StatusBadge, { label: "Pending", variant: "pending" }),
|
|
3603
|
+
/* @__PURE__ */ jsx123(StatusBadge, { label: "Inactive", variant: "inactive" })
|
|
3604
|
+
] }),
|
|
3605
|
+
/* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "20rem", className: "mt-8", children: [
|
|
3606
|
+
/* @__PURE__ */ jsx123(EmptyState, { title: "No records", description: "Use empty states instead of blank panels." }),
|
|
3607
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Skeleton loading", description: "Use while data is loading.", children: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3608
|
+
/* @__PURE__ */ jsx123(Skeleton, { className: "h-4 w-3/4" }),
|
|
3609
|
+
/* @__PURE__ */ jsx123(Skeleton, { className: "h-4 w-1/2" }),
|
|
3610
|
+
/* @__PURE__ */ jsx123(Skeleton, { className: "h-20 w-full" })
|
|
3611
|
+
] }) }),
|
|
3612
|
+
/* @__PURE__ */ jsx123(KeyValueList, { density: "compact", items: [{ keyLabel: "Package", value: "@tapizlabs/ui" }, { keyLabel: "Mode", value: "Framework" }, { keyLabel: "Theme", value: "Token-first" }] })
|
|
3613
|
+
] })
|
|
3614
|
+
] }),
|
|
3615
|
+
/* @__PURE__ */ jsx123(DemoSection, { id: "forms", title: "Forms", description: "Controlled-ready field primitives for enterprise CRUD, settings, onboarding and import flows.", children: /* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "20rem", children: [
|
|
3616
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Fields", children: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3617
|
+
/* @__PURE__ */ jsx123(FormField, { label: "Workspace name", hint: "Shown in the app shell", children: /* @__PURE__ */ jsx123(Input, { placeholder: "Tapiz Academy" }) }),
|
|
3618
|
+
/* @__PURE__ */ jsx123(FormField, { label: "Role", children: /* @__PURE__ */ jsxs96(Select, { children: [
|
|
3619
|
+
/* @__PURE__ */ jsx123("option", { children: "Teacher" }),
|
|
3620
|
+
/* @__PURE__ */ jsx123("option", { children: "Admin" })
|
|
3621
|
+
] }) }),
|
|
3622
|
+
/* @__PURE__ */ jsx123(FormField, { label: "Notes", children: /* @__PURE__ */ jsx123(Textarea, { placeholder: "Internal note" }) })
|
|
3623
|
+
] }) }),
|
|
3624
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Advanced inputs", children: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3625
|
+
/* @__PURE__ */ jsx123(InputGroup, { prefix: "https://", suffix: ".tapiz.app", children: /* @__PURE__ */ jsx123(Input, { placeholder: "school" }) }),
|
|
3626
|
+
/* @__PURE__ */ jsx123(PasswordInput, { placeholder: "Password" }),
|
|
3627
|
+
/* @__PURE__ */ jsx123(Slider, { label: "Automation level", valueLabel: "72%", defaultValue: 72 }),
|
|
3628
|
+
/* @__PURE__ */ jsx123(ToggleGroup, { value: "monthly", options: [{ label: "Monthly", value: "monthly" }, { label: "Yearly", value: "yearly" }] }),
|
|
3629
|
+
/* @__PURE__ */ jsx123(Switch, { label: "Enable notifications", checked: true }),
|
|
3630
|
+
/* @__PURE__ */ jsx123(Combobox, { placeholder: "Choose workspace", options: [{ value: "academy", label: "Academy" }, { value: "enterprise", label: "Enterprise" }] }),
|
|
3631
|
+
/* @__PURE__ */ jsx123(DateRangePicker, {}),
|
|
3632
|
+
/* @__PURE__ */ jsx123(ColorSwatchPicker, { value: "accent", options: [{ value: "accent", label: "Accent", color: "var(--tapiz-accent)" }, { value: "success", label: "Success", color: "var(--tapiz-success)" }, { value: "warning", label: "Warning", color: "var(--tapiz-warning)" }] }),
|
|
3633
|
+
/* @__PURE__ */ jsx123(RatingInput, { value: 4 })
|
|
3634
|
+
] }) }),
|
|
3635
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Upload and text area", children: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3636
|
+
/* @__PURE__ */ jsx123(FileDropzone, { title: "Import CSV", description: "Drag attendance data or click to browse." }),
|
|
3637
|
+
/* @__PURE__ */ jsx123(TextareaCounter, { maxLength: 120, value: "Reusable character-count textarea for messages and descriptions.", readOnly: true })
|
|
3638
|
+
] }) })
|
|
3639
|
+
] }) }),
|
|
3640
|
+
/* @__PURE__ */ jsxs96(DemoSection, { id: "data", title: "Data display", description: "Tables, charts, progress, metrics, filters and visual summaries for dense products.", children: [
|
|
3641
|
+
/* @__PURE__ */ jsx123(
|
|
3642
|
+
DataToolbar,
|
|
3643
|
+
{
|
|
3644
|
+
title: "Students",
|
|
3645
|
+
description: "Search, filter and operate on tabular data.",
|
|
3646
|
+
search: /* @__PURE__ */ jsx123(SearchInput, { placeholder: "Search students", value: "", onChange: () => void 0 }),
|
|
3647
|
+
filters: /* @__PURE__ */ jsxs96(Fragment5, { children: [
|
|
3648
|
+
/* @__PURE__ */ jsx123(FilterChip, { active: true, children: "Active" }),
|
|
3649
|
+
/* @__PURE__ */ jsx123(FilterChip, { children: "Grade 8" }),
|
|
3650
|
+
/* @__PURE__ */ jsx123(FilterChip, { children: "High score" })
|
|
3651
|
+
] }),
|
|
3652
|
+
actions: /* @__PURE__ */ jsx123(Button, { size: "sm", children: "Export" }),
|
|
3653
|
+
className: "mb-4"
|
|
3654
|
+
}
|
|
3655
|
+
),
|
|
3656
|
+
/* @__PURE__ */ jsx123(
|
|
3657
|
+
DataTable,
|
|
3658
|
+
{
|
|
3659
|
+
variant: "enterprise",
|
|
3660
|
+
data: demoRows,
|
|
3661
|
+
rowKey: (row) => row.id,
|
|
3662
|
+
columns: [
|
|
3663
|
+
{ id: "student", header: "Student", cell: (row) => row.student, sortAccessor: (row) => row.student },
|
|
3664
|
+
{ id: "status", header: "Status", cell: (row) => /* @__PURE__ */ jsx123(StatusBadge, { label: row.status, variant: row.status === "Active" ? "success" : row.status === "Pending" ? "pending" : "danger" }) },
|
|
3665
|
+
{ id: "score", header: "Score", cell: (row) => `${row.score}%`, align: "right", sortAccessor: (row) => row.score }
|
|
3666
|
+
]
|
|
3667
|
+
}
|
|
3668
|
+
),
|
|
3669
|
+
/* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "19rem", className: "mt-8", children: [
|
|
3670
|
+
/* @__PURE__ */ jsx123(MetricCard, { label: "Attendance", value: "96.4%", trend: "+4.2%", trendTone: "positive", description: "vs last month" }),
|
|
3671
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Bar list", children: /* @__PURE__ */ jsx123(BarList, { items: [{ label: "Quiz", value: 42 }, { label: "Attendance", value: 68 }, { label: "Assignments", value: 54 }] }) }),
|
|
3672
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Donut", children: /* @__PURE__ */ jsx123(DonutMetric, { value: 82, label: "Completion", caption: "Average across active classes" }) }),
|
|
3673
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Progress", children: /* @__PURE__ */ jsx123(Progress, { value: 64, label: "Migration" }) }),
|
|
3674
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Score ring", children: /* @__PURE__ */ jsx123(ScoreRing, { value: 88, label: "quality" }) }),
|
|
3675
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Heatmap", children: /* @__PURE__ */ jsx123(HeatmapGrid, { cells: Array.from({ length: 35 }, (_, index) => ({ value: index * 7 % 18, title: `Day ${index + 1}` })) }) }),
|
|
3676
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Funnel", children: /* @__PURE__ */ jsx123(FunnelChart, { steps: [{ label: "Visited", value: 1200 }, { label: "Started", value: 820 }, { label: "Completed", value: 540 }] }) }),
|
|
3677
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Comparison", children: /* @__PURE__ */ jsx123(ComparisonMeter, { leftLabel: "Manual", rightLabel: "Automated", value: 72 }) })
|
|
3678
|
+
] })
|
|
3679
|
+
] }),
|
|
3680
|
+
/* @__PURE__ */ jsx123(DemoSection, { id: "navigation", title: "Navigation and disclosure", description: "Application shell, nav bars, tabs, accordion, stepper and overlays.", children: /* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "23rem", children: [
|
|
3681
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "App shell preview", children: /* @__PURE__ */ jsx123(
|
|
3682
|
+
AppShell,
|
|
3683
|
+
{
|
|
3684
|
+
sidebar: /* @__PURE__ */ jsx123(SidebarNav, { groups: [{ label: "Workspace", items: [{ label: "Dashboard", active: true }, { label: "Students" }, { label: "Reports" }] }] }),
|
|
3685
|
+
topbar: /* @__PURE__ */ jsx123(TopNav, { brand: "Tapiz", links: [{ label: "Docs", href: "#top" }] }),
|
|
3686
|
+
children: /* @__PURE__ */ jsx123("div", { className: "p-4 text-sm text-[var(--tapiz-text-muted)]", children: "Shell content slot" })
|
|
3687
|
+
}
|
|
3688
|
+
) }),
|
|
3689
|
+
/* @__PURE__ */ jsxs96(SectionCard, { title: "Tabs and accordion", children: [
|
|
3690
|
+
/* @__PURE__ */ jsx123(Tabs, { activeId: "usage", variant: "boxed", items: [{ id: "usage", label: "Usage", content: "Use tabs for related panels." }, { id: "api", label: "API", content: "Prop-driven and typed." }] }),
|
|
3691
|
+
/* @__PURE__ */ jsx123(Accordion, { className: "mt-4", openIds: ["one"], items: [{ id: "one", title: "Token-first", content: "No raw hex colors in application code." }, { id: "two", title: "Accessible", content: "Keyboard-friendly primitives." }] })
|
|
3692
|
+
] }),
|
|
3693
|
+
/* @__PURE__ */ jsxs96(SectionCard, { title: "Stepper / overlay states", children: [
|
|
3694
|
+
/* @__PURE__ */ jsx123(Stepper, { steps: [{ id: "create", label: "Create", status: "complete" }, { id: "configure", label: "Configure", status: "current" }, { id: "launch", label: "Launch", status: "upcoming" }] }),
|
|
3695
|
+
/* @__PURE__ */ jsxs96(Cluster, { className: "mt-4", children: [
|
|
3696
|
+
/* @__PURE__ */ jsx123(Popover, { trigger: /* @__PURE__ */ jsx123(Button, { size: "sm", children: "Popover" }), children: "Contextual content" }),
|
|
3697
|
+
/* @__PURE__ */ jsx123(Drawer, { open: false, title: "Drawer", children: "Drawer content" })
|
|
3698
|
+
] }),
|
|
3699
|
+
/* @__PURE__ */ jsx123(CommandMenu, { open: false, groups: [{ label: "Actions", items: [{ id: "open-dashboard", label: "Open dashboard" }, { id: "create-class", label: "Create class" }] }] })
|
|
3700
|
+
] })
|
|
3701
|
+
] }) }),
|
|
3702
|
+
/* @__PURE__ */ jsx123(DemoSection, { id: "feedback", title: "Feedback", description: "Alerts, callouts, notifications, health states and loading overlays.", children: /* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "22rem", children: [
|
|
3703
|
+
/* @__PURE__ */ jsx123(Alert2, { tone: "info", title: "Info alert", children: "Use for important inline messages." }),
|
|
3704
|
+
/* @__PURE__ */ jsx123(Callout, { tone: "warning", title: "Migration warning", children: "Review token usage before publishing." }),
|
|
3705
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Notifications", children: /* @__PURE__ */ jsx123(NotificationList, { items: [{ id: "1", title: "New import completed", description: "1,204 rows processed.", time: "2m", unread: true }, { id: "2", title: "Report ready", time: "1h" }] }) }),
|
|
3706
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Health", children: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3707
|
+
/* @__PURE__ */ jsx123(HealthIndicator, { tone: "operational", detail: "99.99%" }),
|
|
3708
|
+
/* @__PURE__ */ jsx123(HealthIndicator, { tone: "degraded", detail: "API latency" }),
|
|
3709
|
+
/* @__PURE__ */ jsx123(HealthIndicator, { tone: "outage", detail: "1 service" }),
|
|
3710
|
+
/* @__PURE__ */ jsx123(InlineStatus, { tone: "success", pulse: true, children: "Realtime sync active" })
|
|
3711
|
+
] }) }),
|
|
3712
|
+
/* @__PURE__ */ jsx123(LoadingOverlay, { visible: true, label: "Syncing", children: /* @__PURE__ */ jsx123("div", { className: "h-28 border border-[var(--tapiz-border-subtle)] bg-[var(--tapiz-bg-surface-muted)]" }) })
|
|
3713
|
+
] }) }),
|
|
3714
|
+
/* @__PURE__ */ jsxs96(DemoSection, { id: "framework", title: "Framework patterns", description: "Higher-level enterprise blocks for admin panels, permissions, integrations, calendars and workflows.", children: [
|
|
3715
|
+
/* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "23rem", children: [
|
|
3716
|
+
/* @__PURE__ */ jsx123(ResourceCard, { title: "Classroom OS", eyebrow: "resource", description: "Reusable resource card for project, course, class or team entities.", status: "Live", meta: "Updated today" }),
|
|
3717
|
+
/* @__PURE__ */ jsx123(IntegrationCard, { name: "Google Classroom", description: "Sync rosters and assignments.", status: "connected", lastSync: "Synced 12m ago" }),
|
|
3718
|
+
/* @__PURE__ */ jsx123(AuditLog, { items: [{ actor: "Danijel", action: "updated permissions", timestamp: "09:42" }, { actor: "System", action: "synced attendance", timestamp: "09:30" }] })
|
|
3719
|
+
] }),
|
|
3720
|
+
/* @__PURE__ */ jsx123(SplitPane, { className: "mt-8", primary: /* @__PURE__ */ jsx123(KanbanBoard, { columns: [{ id: "todo", title: "Todo", items: [{ id: "a", title: "Design docs page", tone: "accent" }] }, { id: "doing", title: "Doing", items: [{ id: "b", title: "Build components", tone: "warning" }] }, { id: "done", title: "Done", items: [{ id: "c", title: "Tokens", tone: "success" }] }] }), secondary: /* @__PURE__ */ jsx123(AccessMatrix, { roles: [{ key: "admin", label: "Admin" }, { key: "teacher", label: "Teacher" }], permissions: [{ key: "users", label: "Manage users", roles: { admin: true, teacher: false } }, { key: "classes", label: "Manage classes", roles: { admin: true, teacher: true } }] }) }),
|
|
3721
|
+
/* @__PURE__ */ jsx123(CalendarGrid, { className: "mt-8", days: calendarDays })
|
|
3722
|
+
] }),
|
|
3723
|
+
/* @__PURE__ */ jsxs96(DemoSection, { id: "advanced", title: "Advanced framework blocks", description: "More product-grade patterns for operations, approvals, feature management, usage, rails and sticky controls.", children: [
|
|
3724
|
+
/* @__PURE__ */ jsx123(StickyBar, { className: "mb-6", children: /* @__PURE__ */ jsxs96(Cluster, { justify: "between", children: [
|
|
3725
|
+
/* @__PURE__ */ jsx123(InlineStatus, { tone: "info", children: "Previewing max component set" }),
|
|
3726
|
+
/* @__PURE__ */ jsx123(Button, { size: "sm", variant: "secondary", children: "Copy layout" })
|
|
3727
|
+
] }) }),
|
|
3728
|
+
/* @__PURE__ */ jsx123(
|
|
3729
|
+
SplitPane,
|
|
3730
|
+
{
|
|
3731
|
+
primary: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3732
|
+
/* @__PURE__ */ jsx123(ApprovalQueue, { items: [{ title: "Publish new grading rubric", requester: "Mila", priority: "high", description: "Requires admin approval before rollout." }, { title: "Invite external mentor", requester: "Vuk", priority: "medium" }] }),
|
|
3733
|
+
/* @__PURE__ */ jsx123(FeatureFlagTable, { flags: [{ key: "ai.quiz", name: "AI quiz generator", description: "Enable assisted quiz creation.", enabled: true, rollout: "80%" }, { key: "reports.v2", name: "Reports v2", description: "New analytics dashboard.", enabled: false, rollout: "Beta" }] })
|
|
3734
|
+
] }),
|
|
3735
|
+
secondary: /* @__PURE__ */ jsx123(PageRail, { title: "Docs rail", items: [{ label: "Forms", href: "#forms", active: true, meta: "12" }, { label: "Data", href: "#data", meta: "9" }, { label: "Framework", href: "#framework", meta: "18" }] })
|
|
3736
|
+
}
|
|
3737
|
+
),
|
|
3738
|
+
/* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "22rem", className: "mt-8", children: [
|
|
3739
|
+
/* @__PURE__ */ jsx123(PlanUsage, { items: [{ label: "Seats", used: 128, limit: 200 }, { label: "Storage", used: 64, limit: 100 }, { label: "Automations", used: 18, limit: 25 }] }),
|
|
3740
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "SLA", children: /* @__PURE__ */ jsxs96(Stack, { children: [
|
|
3741
|
+
/* @__PURE__ */ jsx123(SLAStatus, { label: "API uptime", value: 99 }),
|
|
3742
|
+
/* @__PURE__ */ jsx123(SLAStatus, { label: "Queue latency", value: 91, target: 95 })
|
|
3743
|
+
] }) }),
|
|
3744
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Inbox", children: /* @__PURE__ */ jsx123(InboxList, { items: [{ title: "Import completed", sender: "System", snippet: "Attendance import finished with 0 errors.", time: "2m", unread: true, tag: "Ops" }, { title: "Teacher request", sender: "Ana", snippet: "Needs access to Grade 8 workspace.", time: "1h" }] }) }),
|
|
3745
|
+
/* @__PURE__ */ jsx123(SectionCard, { title: "Activity", children: /* @__PURE__ */ jsx123(ActivityFeed, { items: [{ actor: "Danijel", action: "enabled Reports v2", time: "now" }, { actor: "System", action: "rotated API keys", time: "1h" }] }) })
|
|
3746
|
+
] }),
|
|
3747
|
+
/* @__PURE__ */ jsx123(MasonryGrid, { columns: 3, className: "mt-8", children: ["Token contract", "Component variants", "Agent docs", "A11y states", "Dark mode", "Framework patterns"].map((item) => /* @__PURE__ */ jsxs96(Card, { variant: "brutal", className: "mb-5 break-inside-avoid", children: [
|
|
3748
|
+
/* @__PURE__ */ jsx123("div", { className: "kicker", children: "module" }),
|
|
3749
|
+
/* @__PURE__ */ jsx123("h3", { className: "mt-2 font-semibold", children: item })
|
|
3750
|
+
] }, item)) })
|
|
3751
|
+
] }),
|
|
3752
|
+
/* @__PURE__ */ jsxs96(DemoSection, { id: "marketing", title: "Marketing blocks", description: "Landing-page building blocks for SaaS, education and enterprise presentation pages.", children: [
|
|
3753
|
+
/* @__PURE__ */ jsx123(AnnouncementBar, { action: /* @__PURE__ */ jsx123(Button, { size: "sm", variant: "brutal", children: "Read changelog" }), children: "New Tapiz UI max component pack is available." }),
|
|
3754
|
+
/* @__PURE__ */ jsxs96(FeatureGrid, { children: [
|
|
3755
|
+
/* @__PURE__ */ jsx123(FeatureCard, { title: "Token architecture", description: "Centralized semantic tokens for consistent light/dark UI." }),
|
|
3756
|
+
/* @__PURE__ */ jsx123(FeatureCard, { title: "Framework blocks", description: "Move faster with app shell, tables, forms and overlays." }),
|
|
3757
|
+
/* @__PURE__ */ jsx123(FeatureCard, { title: "Brutal enterprise", description: "Strong borders, sharp rhythm and professional hierarchy." })
|
|
3758
|
+
] }),
|
|
3759
|
+
/* @__PURE__ */ jsx123(StatsBand, { className: "mt-8", items: [{ value: "80+", label: "Components" }, { value: "2", label: "Themes" }, { value: "0", label: "App deps" }] }),
|
|
3760
|
+
/* @__PURE__ */ jsx123(LogoCloud, { className: "mt-8", title: "Works for product surfaces", items: [{ name: "Dashboard" }, { name: "Admin" }, { name: "Landing" }, { name: "Docs" }, { name: "Forms" }, { name: "Data" }] }),
|
|
3761
|
+
/* @__PURE__ */ jsxs96(ResponsiveGrid, { min: "20rem", className: "mt-8", children: [
|
|
3762
|
+
/* @__PURE__ */ jsx123(TestimonialCard, { quote: "Tapiz UI gives the product an instant enterprise backbone.", author: "Design Lead", role: "Tapiz Labs" }),
|
|
3763
|
+
/* @__PURE__ */ jsx123(PricingCard, { name: "Framework", price: "\u20AC0", highlighted: true, features: ["Token system", "Components", "Docs page"] }),
|
|
3764
|
+
/* @__PURE__ */ jsx123(ComparisonTable, { includedHeader: "Tapiz", alternativeHeader: "Ad-hoc UI", rows: [{ feature: "Light/dark", included: "Yes", alternative: "Manual" }, { feature: "Agent docs", included: "Included", alternative: "No" }] })
|
|
3765
|
+
] }),
|
|
3766
|
+
/* @__PURE__ */ jsx123(RoadmapList, { className: "mt-8", items: [{ quarter: "Q1", title: "Core framework", status: "Done", description: "Shell, nav, forms and table primitives." }, { quarter: "Q2", title: "Analytics blocks", status: "Now", description: "Charts, status and operational views." }, { quarter: "Q3", title: "AI workflows", status: "Next", description: "Agent-ready docs and generated screens." }] }),
|
|
3767
|
+
/* @__PURE__ */ jsx123(FAQSection, { className: "mt-8", description: "Common framework usage questions.", items: [{ question: "Can this be used outside Tapiz?", answer: "Yes. Components are generic and token-driven." }, { question: "Does it require app router?", answer: "No. The package avoids app-specific dependencies." }] }),
|
|
3768
|
+
/* @__PURE__ */ jsx123(CTASection, { className: "mt-8", eyebrow: "Ready", title: "Build with Tapiz UI", description: "Copy this page into your docs app or export TapizDocsPage from the package.", actions: /* @__PURE__ */ jsx123(Button, { variant: "primary", children: "Use framework" }) })
|
|
3769
|
+
] }),
|
|
3770
|
+
/* @__PURE__ */ jsx123(DemoSection, { id: "code", title: "Usage snippets", description: "Copyable examples for agents and developers.", children: /* @__PURE__ */ jsx123(CodeBlock, { language: "tsx", children: `import { TapizDocsPage } from "@tapizlabs/ui";
|
|
3771
|
+
import "@tapizlabs/ui/theme.css";
|
|
3772
|
+
|
|
3773
|
+
export default function Docs() {
|
|
3774
|
+
return <TapizDocsPage />;
|
|
3775
|
+
}` }) })
|
|
3776
|
+
] })
|
|
3777
|
+
] });
|
|
3778
|
+
}
|
|
1886
3779
|
export {
|
|
3780
|
+
AccessMatrix,
|
|
3781
|
+
Accordion,
|
|
1887
3782
|
ActionMenu,
|
|
1888
3783
|
Activity,
|
|
3784
|
+
ActivityFeed,
|
|
1889
3785
|
ActivityMenu,
|
|
1890
|
-
Alert,
|
|
3786
|
+
Alert2 as Alert,
|
|
3787
|
+
AnnouncementBar,
|
|
3788
|
+
AppShell,
|
|
1891
3789
|
AppleIcon,
|
|
3790
|
+
ApprovalQueue,
|
|
1892
3791
|
ArrowLeft,
|
|
1893
3792
|
ArrowRight,
|
|
3793
|
+
AuditLog,
|
|
3794
|
+
Avatar,
|
|
1894
3795
|
Badge,
|
|
1895
3796
|
Ban,
|
|
1896
3797
|
BarChart,
|
|
3798
|
+
BarList,
|
|
1897
3799
|
BaseModal,
|
|
1898
3800
|
Bell,
|
|
1899
3801
|
Book,
|
|
3802
|
+
Breadcrumbs,
|
|
1900
3803
|
Button,
|
|
3804
|
+
CTASection,
|
|
1901
3805
|
Calendar,
|
|
3806
|
+
CalendarGrid,
|
|
1902
3807
|
CalendarMonth,
|
|
1903
3808
|
CalendarWeek,
|
|
3809
|
+
Callout,
|
|
1904
3810
|
Card,
|
|
1905
3811
|
CardBody,
|
|
1906
3812
|
CardHeader,
|
|
@@ -1914,15 +3820,28 @@ export {
|
|
|
1914
3820
|
ChevronUp,
|
|
1915
3821
|
Clipboard,
|
|
1916
3822
|
Clock,
|
|
3823
|
+
Cluster,
|
|
3824
|
+
CodeBlock,
|
|
3825
|
+
ColorSwatchPicker,
|
|
3826
|
+
Combobox,
|
|
3827
|
+
CommandMenu,
|
|
1917
3828
|
Compare,
|
|
3829
|
+
ComparisonMeter,
|
|
3830
|
+
ComparisonTable,
|
|
1918
3831
|
ConfirmDialog,
|
|
3832
|
+
Container,
|
|
1919
3833
|
Copy,
|
|
1920
3834
|
Cpu,
|
|
1921
3835
|
CreditCard,
|
|
1922
3836
|
DataTable,
|
|
3837
|
+
DataToolbar,
|
|
1923
3838
|
Database,
|
|
3839
|
+
DateRangePicker,
|
|
1924
3840
|
DefaultErrorFallback,
|
|
3841
|
+
Divider,
|
|
3842
|
+
DonutMetric,
|
|
1925
3843
|
Download,
|
|
3844
|
+
Drawer,
|
|
1926
3845
|
Edit,
|
|
1927
3846
|
EmptyState,
|
|
1928
3847
|
ErrorBoundary,
|
|
@@ -1930,15 +3849,23 @@ export {
|
|
|
1930
3849
|
ExternalLink,
|
|
1931
3850
|
Eye,
|
|
1932
3851
|
EyeOff,
|
|
3852
|
+
FAQSection,
|
|
1933
3853
|
Faculty,
|
|
3854
|
+
FeatureCard,
|
|
3855
|
+
FeatureFlagTable,
|
|
3856
|
+
FeatureGrid,
|
|
1934
3857
|
FieldHint,
|
|
1935
3858
|
FieldLabel,
|
|
3859
|
+
FileDropzone,
|
|
1936
3860
|
FileText,
|
|
1937
3861
|
FileUpload,
|
|
3862
|
+
FilterChip,
|
|
1938
3863
|
FingerprintIcon,
|
|
1939
3864
|
FormError,
|
|
3865
|
+
FormField,
|
|
1940
3866
|
FormIcon,
|
|
1941
3867
|
FormulaIcon,
|
|
3868
|
+
FunnelChart,
|
|
1942
3869
|
Gear,
|
|
1943
3870
|
Globe,
|
|
1944
3871
|
GooglePlayIcon,
|
|
@@ -1947,70 +3874,118 @@ export {
|
|
|
1947
3874
|
GridBg,
|
|
1948
3875
|
HardDrive,
|
|
1949
3876
|
Hash,
|
|
3877
|
+
HealthIndicator,
|
|
3878
|
+
HeatmapGrid,
|
|
1950
3879
|
HelpCircle,
|
|
3880
|
+
HeroFrame,
|
|
1951
3881
|
History,
|
|
1952
3882
|
Home,
|
|
1953
3883
|
Icons,
|
|
1954
3884
|
Image,
|
|
3885
|
+
InboxList,
|
|
1955
3886
|
Info,
|
|
1956
3887
|
InfoBanner,
|
|
3888
|
+
InlineStatus,
|
|
1957
3889
|
Input,
|
|
3890
|
+
InputGroup,
|
|
3891
|
+
IntegrationCard,
|
|
1958
3892
|
Intersect,
|
|
3893
|
+
KanbanBoard,
|
|
3894
|
+
Kbd,
|
|
3895
|
+
KeyValueList,
|
|
1959
3896
|
Layers,
|
|
3897
|
+
LoadingOverlay,
|
|
1960
3898
|
LockIcon,
|
|
1961
3899
|
LogOut,
|
|
3900
|
+
LogoCloud,
|
|
1962
3901
|
LogoMark,
|
|
1963
3902
|
Mail,
|
|
3903
|
+
MarketingShell,
|
|
3904
|
+
MasonryGrid,
|
|
1964
3905
|
Megaphone,
|
|
1965
3906
|
Menu,
|
|
3907
|
+
MetricCard,
|
|
3908
|
+
MockupFrame,
|
|
1966
3909
|
Monitor,
|
|
1967
3910
|
Moon,
|
|
1968
3911
|
NavAnalytics,
|
|
1969
3912
|
NavQrAttendance,
|
|
1970
3913
|
NavScoresheet,
|
|
1971
3914
|
NavSecurity,
|
|
3915
|
+
NotificationList,
|
|
1972
3916
|
NumberIcon,
|
|
1973
3917
|
OfficeHours,
|
|
1974
3918
|
PageHeader,
|
|
3919
|
+
PageRail,
|
|
1975
3920
|
PageSpinner,
|
|
1976
3921
|
Pagination,
|
|
3922
|
+
PasswordInput,
|
|
1977
3923
|
Pdf,
|
|
3924
|
+
PlanUsage,
|
|
1978
3925
|
Plus,
|
|
3926
|
+
Popover,
|
|
3927
|
+
PricingCard,
|
|
1979
3928
|
Printer,
|
|
3929
|
+
Progress,
|
|
1980
3930
|
QrCode,
|
|
1981
3931
|
RadioButton,
|
|
3932
|
+
RatingInput,
|
|
1982
3933
|
Refresh,
|
|
1983
3934
|
RefreshCw,
|
|
1984
3935
|
Repeat,
|
|
1985
3936
|
Report,
|
|
3937
|
+
ResourceCard,
|
|
3938
|
+
ResponsiveGrid,
|
|
3939
|
+
RoadmapList,
|
|
1986
3940
|
RotateCcw,
|
|
3941
|
+
SLAStatus,
|
|
1987
3942
|
Scan,
|
|
3943
|
+
ScoreRing,
|
|
1988
3944
|
Search,
|
|
1989
3945
|
SearchInput,
|
|
3946
|
+
SectionCard,
|
|
1990
3947
|
SectionIcons,
|
|
1991
3948
|
SectionTitle,
|
|
1992
3949
|
Select,
|
|
1993
3950
|
Server,
|
|
1994
3951
|
Shield,
|
|
3952
|
+
SidebarNav,
|
|
1995
3953
|
Skeleton,
|
|
1996
3954
|
SkeletonBanner,
|
|
1997
3955
|
SkeletonCard,
|
|
1998
3956
|
SkeletonKpiCard,
|
|
1999
3957
|
SkeletonPageHeader,
|
|
2000
3958
|
SkeletonTable,
|
|
3959
|
+
Slider,
|
|
2001
3960
|
Smartphone,
|
|
3961
|
+
Sparkline,
|
|
2002
3962
|
Spinner,
|
|
3963
|
+
SplitPane,
|
|
2003
3964
|
Spotlight,
|
|
3965
|
+
Stack,
|
|
2004
3966
|
Star,
|
|
3967
|
+
StatGrid,
|
|
3968
|
+
StatsBand,
|
|
2005
3969
|
StatusBadge,
|
|
3970
|
+
Stepper,
|
|
3971
|
+
StickyBar,
|
|
2006
3972
|
Sun,
|
|
3973
|
+
Surface,
|
|
3974
|
+
Switch,
|
|
2007
3975
|
Table,
|
|
2008
3976
|
Tablet,
|
|
3977
|
+
Tabs,
|
|
3978
|
+
TapizDocsPage,
|
|
3979
|
+
TestimonialCard,
|
|
2009
3980
|
TextIcon,
|
|
2010
3981
|
Textarea,
|
|
3982
|
+
TextareaCounter,
|
|
3983
|
+
Timeline,
|
|
2011
3984
|
Toast,
|
|
2012
3985
|
ToastProvider,
|
|
3986
|
+
ToggleGroup,
|
|
2013
3987
|
Tooltip,
|
|
3988
|
+
TopNav,
|
|
2014
3989
|
Trash,
|
|
2015
3990
|
Trophy,
|
|
2016
3991
|
TwoFAIcon,
|
|
@@ -2023,6 +3998,7 @@ export {
|
|
|
2023
3998
|
Users,
|
|
2024
3999
|
X,
|
|
2025
4000
|
Zap,
|
|
4001
|
+
tapizFrameworkPresets,
|
|
2026
4002
|
useToast
|
|
2027
4003
|
};
|
|
2028
4004
|
//# sourceMappingURL=index.js.map
|