@pattern-stack/frontend-patterns 0.2.0-alpha.15 → 0.2.0-alpha.18
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/CHANGELOG.md +13 -0
- package/dist/atoms/components/data/Duration/Duration.d.ts +11 -0
- package/dist/atoms/components/data/Duration/Duration.d.ts.map +1 -0
- package/dist/atoms/components/data/Duration/index.d.ts +2 -0
- package/dist/atoms/components/data/Duration/index.d.ts.map +1 -0
- package/dist/atoms/components/data/LiveIndicator/LiveIndicator.d.ts +12 -0
- package/dist/atoms/components/data/LiveIndicator/LiveIndicator.d.ts.map +1 -0
- package/dist/atoms/components/data/LiveIndicator/index.d.ts +2 -0
- package/dist/atoms/components/data/LiveIndicator/index.d.ts.map +1 -0
- package/dist/atoms/components/data/Sparkline/Sparkline.d.ts +16 -0
- package/dist/atoms/components/data/Sparkline/Sparkline.d.ts.map +1 -0
- package/dist/atoms/components/data/Sparkline/index.d.ts +2 -0
- package/dist/atoms/components/data/Sparkline/index.d.ts.map +1 -0
- package/dist/atoms/components/data/Timestamp/Timestamp.d.ts +13 -0
- package/dist/atoms/components/data/Timestamp/Timestamp.d.ts.map +1 -0
- package/dist/atoms/components/data/Timestamp/index.d.ts +2 -0
- package/dist/atoms/components/data/Timestamp/index.d.ts.map +1 -0
- package/dist/atoms/components/data/index.d.ts +4 -0
- package/dist/atoms/components/data/index.d.ts.map +1 -1
- package/dist/atoms/types/navigation.d.ts +9 -2
- package/dist/atoms/types/navigation.d.ts.map +1 -1
- package/dist/index.es.js +239 -22
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +239 -22
- package/dist/index.js.map +1 -1
- package/dist/molecules/layout/Sidebar.d.ts.map +1 -1
- package/dist/templates/factory.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7793,6 +7793,201 @@ const TruncatedText = ({
|
|
|
7793
7793
|
}
|
|
7794
7794
|
);
|
|
7795
7795
|
};
|
|
7796
|
+
function formatAuto(ms) {
|
|
7797
|
+
if (ms < 1e3) {
|
|
7798
|
+
return { visible: `${ms}ms`, spoken: `${ms} milliseconds` };
|
|
7799
|
+
}
|
|
7800
|
+
if (ms < 6e4) {
|
|
7801
|
+
const secs = ms / 1e3;
|
|
7802
|
+
return {
|
|
7803
|
+
visible: `${secs.toFixed(1)}s`,
|
|
7804
|
+
spoken: `${secs.toFixed(1)} seconds`
|
|
7805
|
+
};
|
|
7806
|
+
}
|
|
7807
|
+
if (ms < 36e5) {
|
|
7808
|
+
const m = Math.floor(ms / 6e4);
|
|
7809
|
+
const s = Math.round(ms % 6e4 / 1e3);
|
|
7810
|
+
return { visible: `${m}m ${s}s`, spoken: `${m} minutes ${s} seconds` };
|
|
7811
|
+
}
|
|
7812
|
+
if (ms < 864e5) {
|
|
7813
|
+
const h2 = Math.floor(ms / 36e5);
|
|
7814
|
+
const m = Math.round(ms % 36e5 / 6e4);
|
|
7815
|
+
return { visible: `${h2}h ${m}m`, spoken: `${h2} hours ${m} minutes` };
|
|
7816
|
+
}
|
|
7817
|
+
const d = Math.floor(ms / 864e5);
|
|
7818
|
+
const h = Math.round(ms % 864e5 / 36e5);
|
|
7819
|
+
return { visible: `${d}d ${h}h`, spoken: `${d} days ${h} hours` };
|
|
7820
|
+
}
|
|
7821
|
+
function formatS(ms) {
|
|
7822
|
+
const secs = ms / 1e3;
|
|
7823
|
+
return {
|
|
7824
|
+
visible: `${secs.toFixed(1)}s`,
|
|
7825
|
+
spoken: `${secs.toFixed(1)} seconds`
|
|
7826
|
+
};
|
|
7827
|
+
}
|
|
7828
|
+
function formatMs(ms) {
|
|
7829
|
+
return { visible: `${ms}ms`, spoken: `${ms} milliseconds` };
|
|
7830
|
+
}
|
|
7831
|
+
function Duration({ ms, precision = "auto", className }) {
|
|
7832
|
+
const { visible, spoken } = precision === "s" ? formatS(ms) : precision === "ms" ? formatMs(ms) : formatAuto(ms);
|
|
7833
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7834
|
+
"span",
|
|
7835
|
+
{
|
|
7836
|
+
"aria-label": spoken,
|
|
7837
|
+
className: cn("font-mono text-xs text-muted-foreground", className),
|
|
7838
|
+
children: visible
|
|
7839
|
+
}
|
|
7840
|
+
);
|
|
7841
|
+
}
|
|
7842
|
+
function toDate(v) {
|
|
7843
|
+
return v instanceof Date ? v : new Date(v);
|
|
7844
|
+
}
|
|
7845
|
+
function formatRelative(date, now) {
|
|
7846
|
+
const diffMs = now.getTime() - date.getTime();
|
|
7847
|
+
const abs = Math.abs(diffMs);
|
|
7848
|
+
const suffix = diffMs >= 0 ? "ago" : "from now";
|
|
7849
|
+
if (abs < 6e4) return "just now";
|
|
7850
|
+
if (abs < 36e5) {
|
|
7851
|
+
const m = Math.floor(abs / 6e4);
|
|
7852
|
+
return `${m}m ${suffix}`;
|
|
7853
|
+
}
|
|
7854
|
+
if (abs < 864e5) {
|
|
7855
|
+
const h = Math.floor(abs / 36e5);
|
|
7856
|
+
return `${h}h ${suffix}`;
|
|
7857
|
+
}
|
|
7858
|
+
if (abs < 6048e5) {
|
|
7859
|
+
const d = Math.floor(abs / 864e5);
|
|
7860
|
+
return d === 1 ? "yesterday" : `${d}d ${suffix}`;
|
|
7861
|
+
}
|
|
7862
|
+
return date.toLocaleDateString(void 0);
|
|
7863
|
+
}
|
|
7864
|
+
function formatAbsolute(date, tz) {
|
|
7865
|
+
return date.toLocaleString(void 0, {
|
|
7866
|
+
dateStyle: "short",
|
|
7867
|
+
timeStyle: "short",
|
|
7868
|
+
timeZone: tz
|
|
7869
|
+
});
|
|
7870
|
+
}
|
|
7871
|
+
function Timestamp({
|
|
7872
|
+
value,
|
|
7873
|
+
format = "relative",
|
|
7874
|
+
tz,
|
|
7875
|
+
className
|
|
7876
|
+
}) {
|
|
7877
|
+
const date = toDate(value);
|
|
7878
|
+
const iso = date.toISOString();
|
|
7879
|
+
const [now, setNow] = React.useState(() => /* @__PURE__ */ new Date());
|
|
7880
|
+
React.useEffect(() => {
|
|
7881
|
+
if (format === "absolute") return;
|
|
7882
|
+
const id = setInterval(() => setNow(/* @__PURE__ */ new Date()), 3e4);
|
|
7883
|
+
return () => clearInterval(id);
|
|
7884
|
+
}, [format]);
|
|
7885
|
+
const absolute = formatAbsolute(date, tz);
|
|
7886
|
+
const relative = formatRelative(date, now);
|
|
7887
|
+
const display = format === "relative" ? relative : absolute;
|
|
7888
|
+
const title = format === "both" ? relative : void 0;
|
|
7889
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7890
|
+
"time",
|
|
7891
|
+
{
|
|
7892
|
+
dateTime: iso,
|
|
7893
|
+
title,
|
|
7894
|
+
className: cn("font-mono text-xs text-muted-foreground", className),
|
|
7895
|
+
children: display
|
|
7896
|
+
}
|
|
7897
|
+
);
|
|
7898
|
+
}
|
|
7899
|
+
function Sparkline({
|
|
7900
|
+
data,
|
|
7901
|
+
width = 140,
|
|
7902
|
+
height = 28,
|
|
7903
|
+
color = "hsl(var(--muted-foreground))",
|
|
7904
|
+
fill,
|
|
7905
|
+
strokeWidth = 1.2,
|
|
7906
|
+
markLast = false
|
|
7907
|
+
}) {
|
|
7908
|
+
if (data.length < 2) {
|
|
7909
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width, height, "aria-hidden": true });
|
|
7910
|
+
}
|
|
7911
|
+
const min = Math.min(...data);
|
|
7912
|
+
const max = Math.max(...data);
|
|
7913
|
+
const range = max - min || 1;
|
|
7914
|
+
const pad = strokeWidth;
|
|
7915
|
+
const innerW = width - pad * 2;
|
|
7916
|
+
const innerH = height - pad * 2;
|
|
7917
|
+
const points = data.map((v, i) => {
|
|
7918
|
+
const x = pad + i / (data.length - 1) * innerW;
|
|
7919
|
+
const y = pad + innerH - (v - min) / range * innerH;
|
|
7920
|
+
return [x, y];
|
|
7921
|
+
});
|
|
7922
|
+
const polyline = points.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
7923
|
+
const firstPt = points[0];
|
|
7924
|
+
const lastPt = points[points.length - 1];
|
|
7925
|
+
let fillPath;
|
|
7926
|
+
if (fill) {
|
|
7927
|
+
fillPath = [
|
|
7928
|
+
`${firstPt[0].toFixed(2)},${(pad + innerH).toFixed(2)}`,
|
|
7929
|
+
...points.map(([x, y]) => `${x.toFixed(2)},${y.toFixed(2)}`),
|
|
7930
|
+
`${lastPt[0].toFixed(2)},${(pad + innerH).toFixed(2)}`
|
|
7931
|
+
].join(" ");
|
|
7932
|
+
}
|
|
7933
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7934
|
+
"svg",
|
|
7935
|
+
{
|
|
7936
|
+
width,
|
|
7937
|
+
height,
|
|
7938
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
7939
|
+
"aria-hidden": true,
|
|
7940
|
+
style: { display: "block", overflow: "visible" },
|
|
7941
|
+
children: [
|
|
7942
|
+
fillPath && /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: fillPath, fill, stroke: "none" }),
|
|
7943
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7944
|
+
"polyline",
|
|
7945
|
+
{
|
|
7946
|
+
points: polyline,
|
|
7947
|
+
fill: "none",
|
|
7948
|
+
stroke: color,
|
|
7949
|
+
strokeWidth,
|
|
7950
|
+
strokeLinejoin: "round",
|
|
7951
|
+
strokeLinecap: "round"
|
|
7952
|
+
}
|
|
7953
|
+
),
|
|
7954
|
+
markLast && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: lastPt[0], cy: lastPt[1], r: strokeWidth * 2, fill: color })
|
|
7955
|
+
]
|
|
7956
|
+
}
|
|
7957
|
+
);
|
|
7958
|
+
}
|
|
7959
|
+
function LiveIndicator({
|
|
7960
|
+
active,
|
|
7961
|
+
label = "Live",
|
|
7962
|
+
className
|
|
7963
|
+
}) {
|
|
7964
|
+
const ariaLabel = active ? `${label} — connected` : `${label} — paused`;
|
|
7965
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7966
|
+
"span",
|
|
7967
|
+
{
|
|
7968
|
+
role: "status",
|
|
7969
|
+
"aria-live": "polite",
|
|
7970
|
+
"aria-label": ariaLabel,
|
|
7971
|
+
className: cn(
|
|
7972
|
+
"inline-flex items-center gap-2 text-xs font-mono",
|
|
7973
|
+
active ? "text-primary" : "text-muted-foreground",
|
|
7974
|
+
className
|
|
7975
|
+
),
|
|
7976
|
+
children: [
|
|
7977
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7978
|
+
"span",
|
|
7979
|
+
{
|
|
7980
|
+
className: cn(
|
|
7981
|
+
"inline-block w-2 h-2 rounded-full",
|
|
7982
|
+
active ? "bg-primary animate-pulse" : "bg-muted-foreground/40"
|
|
7983
|
+
)
|
|
7984
|
+
}
|
|
7985
|
+
),
|
|
7986
|
+
label
|
|
7987
|
+
]
|
|
7988
|
+
}
|
|
7989
|
+
);
|
|
7990
|
+
}
|
|
7796
7991
|
const defaultActivityIconMap = {
|
|
7797
7992
|
user: {
|
|
7798
7993
|
icon: lucideReact.Users,
|
|
@@ -10644,7 +10839,7 @@ const SidebarButton = ({
|
|
|
10644
10839
|
"span",
|
|
10645
10840
|
{
|
|
10646
10841
|
className: cn(
|
|
10647
|
-
"text-sm font-medium flex-1 text-left",
|
|
10842
|
+
"text-sm font-medium flex-1 text-left whitespace-nowrap",
|
|
10648
10843
|
active ? `text-category-${category}` : "text-foreground"
|
|
10649
10844
|
),
|
|
10650
10845
|
children: label
|
|
@@ -10727,23 +10922,43 @@ const Sidebar = ({
|
|
|
10727
10922
|
"data-component-name": "Sidebar",
|
|
10728
10923
|
"data-collapsed": !isExpanded,
|
|
10729
10924
|
children: [
|
|
10730
|
-
/* @__PURE__ */ jsxRuntime.
|
|
10731
|
-
"
|
|
10925
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
10926
|
+
"div",
|
|
10732
10927
|
{
|
|
10733
|
-
onClick: toggleSidebar,
|
|
10734
10928
|
className: cn(
|
|
10735
|
-
"
|
|
10736
|
-
"
|
|
10737
|
-
"flex items-center justify-center",
|
|
10738
|
-
"hover:bg-muted hover:text-foreground",
|
|
10739
|
-
"active:scale-95",
|
|
10740
|
-
"transition-all duration-150 ease-out"
|
|
10929
|
+
"flex items-center p-3 pt-4",
|
|
10930
|
+
isExpanded ? "justify-between gap-2" : "justify-center"
|
|
10741
10931
|
),
|
|
10742
|
-
"data-component-name": "
|
|
10743
|
-
|
|
10744
|
-
|
|
10932
|
+
"data-component-name": "SidebarHeader",
|
|
10933
|
+
children: [
|
|
10934
|
+
isExpanded && (navigation == null ? void 0 : navigation.logo) != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10935
|
+
"div",
|
|
10936
|
+
{
|
|
10937
|
+
className: "flex-1 min-w-0 flex items-center",
|
|
10938
|
+
"data-component-name": "SidebarLogo",
|
|
10939
|
+
children: typeof navigation.logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-foreground truncate", children: navigation.logo }) : navigation.logo
|
|
10940
|
+
}
|
|
10941
|
+
),
|
|
10942
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10943
|
+
"button",
|
|
10944
|
+
{
|
|
10945
|
+
onClick: toggleSidebar,
|
|
10946
|
+
className: cn(
|
|
10947
|
+
"w-7 h-7 rounded-md shrink-0",
|
|
10948
|
+
"bg-muted/50 text-muted-foreground",
|
|
10949
|
+
"flex items-center justify-center",
|
|
10950
|
+
"hover:bg-muted hover:text-foreground",
|
|
10951
|
+
"active:scale-95",
|
|
10952
|
+
"transition-all duration-150 ease-out"
|
|
10953
|
+
),
|
|
10954
|
+
"data-component-name": "SidebarToggle",
|
|
10955
|
+
title: !isExpanded ? "Expand sidebar" : "Collapse sidebar",
|
|
10956
|
+
children: !isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5" })
|
|
10957
|
+
}
|
|
10958
|
+
)
|
|
10959
|
+
]
|
|
10745
10960
|
}
|
|
10746
|
-
)
|
|
10961
|
+
),
|
|
10747
10962
|
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex-1 p-3 space-y-2", "data-component-name": "SidebarNav", children: items.map((item) => {
|
|
10748
10963
|
const [itemBasePath, itemQuery] = item.path.split("?");
|
|
10749
10964
|
const currentPath = location.pathname;
|
|
@@ -15720,14 +15935,12 @@ function createReactApp(config) {
|
|
|
15720
15935
|
if (enableRouting) {
|
|
15721
15936
|
tree = /* @__PURE__ */ jsxRuntime.jsx(NavigationProvider, { initialNavigation: navigation, children: /* @__PURE__ */ jsxRuntime.jsx(SidebarProvider, { children: tree }) });
|
|
15722
15937
|
}
|
|
15723
|
-
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
|
|
15728
|
-
|
|
15729
|
-
tree = /* @__PURE__ */ jsxRuntime.jsx(AuthProvider, { config: auth, children: tree });
|
|
15730
|
-
}
|
|
15938
|
+
const authMode = (auth == null ? void 0 : auth.mode) || "pattern-stack";
|
|
15939
|
+
if (enableAuth && authMode !== "none") {
|
|
15940
|
+
tree = /* @__PURE__ */ jsxRuntime.jsx(AuthProvider, { config: auth, children: tree });
|
|
15941
|
+
} else {
|
|
15942
|
+
setGlobalAuthService(null);
|
|
15943
|
+
tree = /* @__PURE__ */ jsxRuntime.jsx(NoAuthProvider, { children: tree });
|
|
15731
15944
|
}
|
|
15732
15945
|
if (enableQuery) {
|
|
15733
15946
|
tree = /* @__PURE__ */ jsxRuntime.jsxs(reactQuery.QueryClientProvider, { client: queryClient, children: [
|
|
@@ -19193,6 +19406,7 @@ exports.DropdownMenuSub = DropdownMenuSub;
|
|
|
19193
19406
|
exports.DropdownMenuSubContent = DropdownMenuSubContent;
|
|
19194
19407
|
exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger;
|
|
19195
19408
|
exports.DropdownMenuTrigger = DropdownMenuTrigger;
|
|
19409
|
+
exports.Duration = Duration;
|
|
19196
19410
|
exports.EmptyState = EmptyState;
|
|
19197
19411
|
exports.EnhancedDataTemplate = EnhancedDataTemplate;
|
|
19198
19412
|
exports.EntityIcon = EntityIcon;
|
|
@@ -19212,6 +19426,7 @@ exports.Label = Label;
|
|
|
19212
19426
|
exports.ListCard = ListCard;
|
|
19213
19427
|
exports.ListPageTemplate = ListPageTemplate;
|
|
19214
19428
|
exports.ListToolbar = ListToolbar;
|
|
19429
|
+
exports.LiveIndicator = LiveIndicator;
|
|
19215
19430
|
exports.Loading = Loading;
|
|
19216
19431
|
exports.LoginForm = LoginForm;
|
|
19217
19432
|
exports.LogoutButton = LogoutButton;
|
|
@@ -19256,6 +19471,7 @@ exports.SkeletonAvatar = SkeletonAvatar;
|
|
|
19256
19471
|
exports.SkeletonButton = SkeletonButton;
|
|
19257
19472
|
exports.SkeletonCard = SkeletonCard;
|
|
19258
19473
|
exports.SkeletonText = SkeletonText;
|
|
19474
|
+
exports.Sparkline = Sparkline;
|
|
19259
19475
|
exports.Spinner = Spinner;
|
|
19260
19476
|
exports.StatCard = StatCard;
|
|
19261
19477
|
exports.StyleGuide = StyleGuide;
|
|
@@ -19273,6 +19489,7 @@ exports.Tabs = Tabs;
|
|
|
19273
19489
|
exports.TabsContent = TabsContent;
|
|
19274
19490
|
exports.TabsList = TabsList;
|
|
19275
19491
|
exports.TabsTrigger = TabsTrigger;
|
|
19492
|
+
exports.Timestamp = Timestamp;
|
|
19276
19493
|
exports.Toast = Toast;
|
|
19277
19494
|
exports.ToastContainer = ToastContainer;
|
|
19278
19495
|
exports.Tooltip = Tooltip;
|