@lindaui/blocks 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -0
  3. package/dist/area-chart.d.ts +11 -0
  4. package/dist/area-chart.d.ts.map +1 -0
  5. package/dist/area-chart.js +65 -0
  6. package/dist/auth-layout.d.ts +26 -0
  7. package/dist/auth-layout.d.ts.map +1 -0
  8. package/dist/auth-layout.js +85 -0
  9. package/dist/auth-provider.d.ts +13 -0
  10. package/dist/auth-provider.d.ts.map +1 -0
  11. package/dist/auth-provider.js +20 -0
  12. package/dist/bar-chart.d.ts +11 -0
  13. package/dist/bar-chart.d.ts.map +1 -0
  14. package/dist/bar-chart.js +64 -0
  15. package/dist/chart-card.d.ts +11 -0
  16. package/dist/chart-card.d.ts.map +1 -0
  17. package/dist/chart-card.js +43 -0
  18. package/dist/confirm-dialog.d.ts +19 -0
  19. package/dist/confirm-dialog.d.ts.map +1 -0
  20. package/dist/confirm-dialog.js +57 -0
  21. package/dist/detail-panel.d.ts +25 -0
  22. package/dist/detail-panel.d.ts.map +1 -0
  23. package/dist/detail-panel.js +116 -0
  24. package/dist/document-panel.d.ts +15 -0
  25. package/dist/document-panel.d.ts.map +1 -0
  26. package/dist/document-panel.js +80 -0
  27. package/dist/document-reader.d.ts +5 -0
  28. package/dist/document-reader.d.ts.map +1 -0
  29. package/dist/document-reader.js +27 -0
  30. package/dist/field-array-form.d.ts +30 -0
  31. package/dist/field-array-form.d.ts.map +1 -0
  32. package/dist/field-array-form.js +132 -0
  33. package/dist/image-viewer.d.ts +14 -0
  34. package/dist/image-viewer.d.ts.map +1 -0
  35. package/dist/image-viewer.js +108 -0
  36. package/dist/line-chart.d.ts +11 -0
  37. package/dist/line-chart.d.ts.map +1 -0
  38. package/dist/line-chart.js +44 -0
  39. package/dist/list-item.d.ts +16 -0
  40. package/dist/list-item.d.ts.map +1 -0
  41. package/dist/list-item.js +50 -0
  42. package/dist/list-pane.d.ts +27 -0
  43. package/dist/list-pane.d.ts.map +1 -0
  44. package/dist/list-pane.js +136 -0
  45. package/dist/login-form.d.ts +18 -0
  46. package/dist/login-form.d.ts.map +1 -0
  47. package/dist/login-form.js +109 -0
  48. package/dist/pie-chart.d.ts +12 -0
  49. package/dist/pie-chart.d.ts.map +1 -0
  50. package/dist/pie-chart.js +49 -0
  51. package/dist/radar-chart.d.ts +11 -0
  52. package/dist/radar-chart.d.ts.map +1 -0
  53. package/dist/radar-chart.js +37 -0
  54. package/dist/radial-chart.d.ts +12 -0
  55. package/dist/radial-chart.d.ts.map +1 -0
  56. package/dist/radial-chart.js +91 -0
  57. package/dist/recording-overlay.d.ts +13 -0
  58. package/dist/recording-overlay.d.ts.map +1 -0
  59. package/dist/recording-overlay.js +128 -0
  60. package/dist/split-workspace.d.ts +9 -0
  61. package/dist/split-workspace.d.ts.map +1 -0
  62. package/dist/split-workspace.js +50 -0
  63. package/dist/stat-card.d.ts +27 -0
  64. package/dist/stat-card.d.ts.map +1 -0
  65. package/dist/stat-card.js +166 -0
  66. package/dist/stats-grid.d.ts +8 -0
  67. package/dist/stats-grid.d.ts.map +1 -0
  68. package/dist/stats-grid.js +15 -0
  69. package/package.json +149 -0
@@ -0,0 +1,128 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { AlertCircle, Mic } from 'lucide-react';
4
+
5
+ function fmtTime(sec) {
6
+ const m = Math.floor(sec / 60);
7
+ const s = sec % 60;
8
+ return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
9
+ }
10
+ function Waveform() {
11
+ return /*#__PURE__*/ jsx("div", {
12
+ className: "flex items-end justify-center gap-[3px]",
13
+ style: {
14
+ height: 48,
15
+ width: "min(80%, 280px)"
16
+ },
17
+ children: Array.from({
18
+ length: 40
19
+ }).map((_, i)=>{
20
+ const seed = Math.abs(Math.sin(i * 12.9898) * 43758.5453) % 1;
21
+ const max = Math.max(6, (0.18 + seed * 0.82) * 48);
22
+ return /*#__PURE__*/ jsx("span", {
23
+ className: "rounded-full bg-destructive",
24
+ style: {
25
+ width: 3,
26
+ animation: `ti-wf 0.9s ease-in-out ${i % 11 * 0.07}s infinite`,
27
+ "--wfmax": `${max}px`
28
+ }
29
+ }, i);
30
+ })
31
+ });
32
+ }
33
+ function RecordingOverlay({ label, description, elapsed, error, onStop, onCancel, stopLabel = "Detener", errorTitle = "No se pudo acceder al micrófono", backLabel = "Volver" }) {
34
+ if (error) {
35
+ return /*#__PURE__*/ jsxs("div", {
36
+ className: "absolute inset-0 z-[60] flex flex-col items-center justify-center gap-5 bg-[oklch(0.16_0.02_240)] p-8 text-center",
37
+ children: [
38
+ /*#__PURE__*/ jsx("div", {
39
+ className: "grid h-16 w-16 place-items-center rounded-full bg-destructive/15 text-destructive",
40
+ children: /*#__PURE__*/ jsx(AlertCircle, {
41
+ className: "h-8 w-8"
42
+ })
43
+ }),
44
+ /*#__PURE__*/ jsxs("div", {
45
+ className: "max-w-[280px]",
46
+ children: [
47
+ /*#__PURE__*/ jsx("p", {
48
+ className: "text-base font-semibold text-white",
49
+ children: errorTitle
50
+ }),
51
+ /*#__PURE__*/ jsx("p", {
52
+ className: "mt-2 text-sm text-white/65",
53
+ children: error
54
+ })
55
+ ]
56
+ }),
57
+ /*#__PURE__*/ jsx("button", {
58
+ type: "button",
59
+ onClick: onCancel,
60
+ className: "h-12 rounded-2xl bg-white px-6 text-[15px] font-semibold text-[oklch(0.16_0.02_240)]",
61
+ children: backLabel
62
+ })
63
+ ]
64
+ });
65
+ }
66
+ return /*#__PURE__*/ jsxs("div", {
67
+ className: "absolute inset-0 z-[60] flex flex-col items-center justify-center gap-5 bg-[oklch(0.16_0.02_240)] text-[oklch(0.9_0.01_220)] sm:gap-7",
68
+ children: [
69
+ /*#__PURE__*/ jsxs("div", {
70
+ className: "relative grid h-[132px] w-[132px] place-items-center sm:h-[168px] sm:w-[168px]",
71
+ children: [
72
+ /*#__PURE__*/ jsx("span", {
73
+ className: "ti-rec-pulse absolute h-[132px] w-[132px] rounded-full bg-destructive/15 sm:h-[168px] sm:w-[168px]"
74
+ }),
75
+ /*#__PURE__*/ jsx("span", {
76
+ className: "ti-rec-pulse absolute h-[132px] w-[132px] rounded-full bg-destructive/15 sm:h-[168px] sm:w-[168px]",
77
+ style: {
78
+ animationDelay: "0.9s"
79
+ }
80
+ }),
81
+ /*#__PURE__*/ jsx("div", {
82
+ className: "grid h-[84px] w-[84px] place-items-center rounded-full bg-destructive text-white shadow-[0_10px_30px_-6px_var(--destructive)] sm:h-[108px] sm:w-[108px]",
83
+ children: /*#__PURE__*/ jsx(Mic, {
84
+ className: "h-8 w-8 sm:h-[42px] sm:w-[42px]"
85
+ })
86
+ })
87
+ ]
88
+ }),
89
+ /*#__PURE__*/ jsxs("div", {
90
+ className: "text-center",
91
+ children: [
92
+ /*#__PURE__*/ jsxs("div", {
93
+ className: "inline-flex items-center gap-2",
94
+ children: [
95
+ /*#__PURE__*/ jsx("span", {
96
+ className: "ti-rec-blink h-2.5 w-2.5 rounded-full bg-destructive"
97
+ }),
98
+ /*#__PURE__*/ jsx("span", {
99
+ className: "text-sm font-semibold tracking-wide text-[oklch(0.72_0.16_18)]",
100
+ children: label
101
+ })
102
+ ]
103
+ }),
104
+ /*#__PURE__*/ jsx("div", {
105
+ className: "mt-2 font-mono text-4xl font-medium tabular-nums text-white sm:text-[46px]",
106
+ children: fmtTime(elapsed)
107
+ })
108
+ ]
109
+ }),
110
+ /*#__PURE__*/ jsx(Waveform, {}),
111
+ description && /*#__PURE__*/ jsx("p", {
112
+ className: "max-w-[270px] text-center text-sm leading-relaxed text-white/70",
113
+ children: description
114
+ }),
115
+ /*#__PURE__*/ jsx("button", {
116
+ type: "button",
117
+ onClick: onStop,
118
+ className: "mt-1.5 grid h-16 w-16 place-items-center rounded-full bg-white shadow-[0_6px_20px_-4px_rgba(0,0,0,0.5)]",
119
+ "aria-label": stopLabel,
120
+ children: /*#__PURE__*/ jsx("span", {
121
+ className: "h-6 w-6 rounded-md bg-destructive"
122
+ })
123
+ })
124
+ ]
125
+ });
126
+ }
127
+
128
+ export { RecordingOverlay };
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ export interface SplitWorkspaceProps {
3
+ media: ReactNode;
4
+ panel: ReactNode;
5
+ overlay?: ReactNode;
6
+ back?: ReactNode;
7
+ }
8
+ export declare function SplitWorkspace({ media, panel, overlay, back, }: SplitWorkspaceProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=split-workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split-workspace.d.ts","sourceRoot":"","sources":["../src/split-workspace.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,OAAO,EACP,IAAI,GACL,EAAE,mBAAmB,+BAuCrB"}
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useIsDesktop } from '@lindaui/ui/use-media-query';
4
+
5
+ function SplitWorkspace({ media, panel, overlay, back }) {
6
+ const isDesktop = useIsDesktop();
7
+ return /*#__PURE__*/ jsxs("div", {
8
+ className: "relative flex-1 min-h-0 overflow-hidden",
9
+ children: [
10
+ isDesktop ? /* Desktop: two-column grid */ /*#__PURE__*/ jsxs("div", {
11
+ className: "grid grid-cols-2 h-full",
12
+ children: [
13
+ /*#__PURE__*/ jsx("div", {
14
+ className: "relative border-r overflow-hidden",
15
+ style: {
16
+ borderColor: "var(--viewer-border)"
17
+ },
18
+ children: media
19
+ }),
20
+ /*#__PURE__*/ jsx("div", {
21
+ className: "flex flex-col bg-background h-full min-h-0 overflow-hidden px-0 sm:px-0",
22
+ children: panel
23
+ })
24
+ ]
25
+ }) : /* Mobile: media top, panel stacked below */ /*#__PURE__*/ jsxs("div", {
26
+ className: "flex flex-col h-full",
27
+ children: [
28
+ /*#__PURE__*/ jsx("div", {
29
+ className: "relative min-h-[40%] flex-1 min-h-0 overflow-hidden",
30
+ children: media
31
+ }),
32
+ /*#__PURE__*/ jsx("div", {
33
+ className: "rounded-t-2xl bg-background shadow-lg overflow-y-auto max-h-[65%] sm:max-h-[60%]",
34
+ children: panel
35
+ })
36
+ ]
37
+ }),
38
+ back && /*#__PURE__*/ jsx("div", {
39
+ className: "absolute left-3.5 top-3 z-40",
40
+ children: back
41
+ }),
42
+ overlay && /*#__PURE__*/ jsx("div", {
43
+ className: "absolute inset-0 z-[60]",
44
+ children: overlay
45
+ })
46
+ ]
47
+ });
48
+ }
49
+
50
+ export { SplitWorkspace };
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from "react";
2
+ export interface StatCardDelta {
3
+ value: string;
4
+ trend: "up" | "down" | "neutral";
5
+ }
6
+ export interface StatCardSparkline {
7
+ data: Array<Record<string, number>>;
8
+ dataKey: string;
9
+ color?: string;
10
+ }
11
+ export type StatCardTone = "primary" | "success" | "warning" | "danger" | "neutral";
12
+ export interface StatCardProps {
13
+ label: ReactNode;
14
+ value: ReactNode;
15
+ delta?: StatCardDelta;
16
+ description?: ReactNode;
17
+ icon?: ReactNode;
18
+ sparkline?: StatCardSparkline;
19
+ /** "featured" = icono prominente arriba-izquierda + delta arriba-derecha +
20
+ * valor grande + label abajo (estilo dashboard). Default = icono inline. */
21
+ variant?: "default" | "featured";
22
+ /** Tinte del icon box (y del valor en featured). Solo aplica a featured. */
23
+ tone?: StatCardTone;
24
+ className?: string;
25
+ }
26
+ export declare function StatCard({ label, value, delta, description, icon, sparkline, variant, tone, className, }: StatCardProps): import("react").JSX.Element;
27
+ //# sourceMappingURL=stat-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../src/stat-card.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B;iFAC6E;IAC7E,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACjC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsDD,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,KAAK,EACL,WAAW,EACX,IAAI,EACJ,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,SAAc,GACf,EAAE,aAAa,+BA6Cf"}
@@ -0,0 +1,166 @@
1
+ 'use client';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { Minus, TrendingDown, TrendingUp } from 'lucide-react';
4
+ import { Card, CardContent, CardHeader, CardTitle } from '@lindaui/ui/card';
5
+ import { Badge } from '@lindaui/ui/badge';
6
+ import { ChartContainer } from '@lindaui/ui/chart';
7
+ import { LineChart, Line } from 'recharts';
8
+
9
+ const trendIcon = {
10
+ up: /*#__PURE__*/ jsx(TrendingUp, {
11
+ className: "h-3 w-3"
12
+ }),
13
+ down: /*#__PURE__*/ jsx(TrendingDown, {
14
+ className: "h-3 w-3"
15
+ }),
16
+ neutral: /*#__PURE__*/ jsx(Minus, {
17
+ className: "h-3 w-3"
18
+ })
19
+ };
20
+ const trendVariant = {
21
+ up: "success",
22
+ down: "danger",
23
+ neutral: "default"
24
+ };
25
+ // Tonos via arbitrary values sobre los tokens canónicos (robustos: no dependen
26
+ // de que HeroUI exponga text-success/text-warning como utilities).
27
+ const toneStyles = {
28
+ primary: {
29
+ box: "bg-[var(--primary)]/10 text-[var(--primary)]",
30
+ value: "text-[var(--primary)]"
31
+ },
32
+ success: {
33
+ box: "bg-[var(--success)]/12 text-[var(--success)]",
34
+ value: "text-[var(--success)]"
35
+ },
36
+ warning: {
37
+ box: "bg-[var(--warning)]/12 text-[var(--warning)]",
38
+ value: "text-[var(--warning)]"
39
+ },
40
+ danger: {
41
+ box: "bg-[var(--destructive)]/10 text-[var(--destructive)]",
42
+ value: "text-[var(--destructive)]"
43
+ },
44
+ neutral: {
45
+ box: "bg-secondary text-muted-foreground",
46
+ value: "text-foreground"
47
+ }
48
+ };
49
+ function DeltaBadge({ delta }) {
50
+ return /*#__PURE__*/ jsx(Badge, {
51
+ variant: trendVariant[delta.trend],
52
+ children: /*#__PURE__*/ jsxs("span", {
53
+ className: "flex items-center gap-0.5",
54
+ children: [
55
+ trendIcon[delta.trend],
56
+ delta.value
57
+ ]
58
+ })
59
+ });
60
+ }
61
+ function Sparkline({ sparkline }) {
62
+ const config = {
63
+ [sparkline.dataKey]: {
64
+ color: sparkline.color ?? "var(--chart-1)"
65
+ }
66
+ };
67
+ return /*#__PURE__*/ jsx(ChartContainer, {
68
+ config: config,
69
+ className: "mt-3 h-12 w-full",
70
+ children: /*#__PURE__*/ jsx(LineChart, {
71
+ data: sparkline.data,
72
+ children: /*#__PURE__*/ jsx(Line, {
73
+ type: "monotone",
74
+ dataKey: sparkline.dataKey,
75
+ stroke: sparkline.color ?? "var(--chart-1)",
76
+ strokeWidth: 2,
77
+ dot: false
78
+ })
79
+ })
80
+ });
81
+ }
82
+ function StatCard({ label, value, delta, description, icon, sparkline, variant = "default", tone = "neutral", className = "" }) {
83
+ if (variant === "featured") {
84
+ const t = toneStyles[tone];
85
+ return /*#__PURE__*/ jsx(Card, {
86
+ className: className,
87
+ children: /*#__PURE__*/ jsxs(CardContent, {
88
+ className: "p-5",
89
+ children: [
90
+ /*#__PURE__*/ jsxs("div", {
91
+ className: "flex items-start justify-between gap-2",
92
+ children: [
93
+ icon && /*#__PURE__*/ jsx("div", {
94
+ className: `grid size-11 shrink-0 place-items-center rounded-xl ${t.box}`,
95
+ children: icon
96
+ }),
97
+ delta && /*#__PURE__*/ jsx(DeltaBadge, {
98
+ delta: delta
99
+ })
100
+ ]
101
+ }),
102
+ /*#__PURE__*/ jsx("div", {
103
+ className: `mt-4 text-3xl font-semibold tabular-nums ${t.value}`,
104
+ children: value
105
+ }),
106
+ /*#__PURE__*/ jsx("div", {
107
+ className: "mt-1 text-sm text-muted-foreground",
108
+ children: label
109
+ }),
110
+ description && /*#__PURE__*/ jsx("p", {
111
+ className: "mt-1.5 text-xs text-muted-foreground",
112
+ children: description
113
+ }),
114
+ sparkline && /*#__PURE__*/ jsx(Sparkline, {
115
+ sparkline: sparkline
116
+ })
117
+ ]
118
+ })
119
+ });
120
+ }
121
+ return /*#__PURE__*/ jsxs(Card, {
122
+ className: className,
123
+ children: [
124
+ /*#__PURE__*/ jsx(CardHeader, {
125
+ className: "pb-2",
126
+ children: /*#__PURE__*/ jsxs("div", {
127
+ className: "flex items-center justify-between gap-2",
128
+ children: [
129
+ /*#__PURE__*/ jsx(CardTitle, {
130
+ className: "text-sm font-medium text-muted-foreground",
131
+ children: label
132
+ }),
133
+ icon && /*#__PURE__*/ jsx("div", {
134
+ className: "h-4 w-4 text-muted-foreground",
135
+ children: icon
136
+ })
137
+ ]
138
+ })
139
+ }),
140
+ /*#__PURE__*/ jsxs(CardContent, {
141
+ className: "pt-0",
142
+ children: [
143
+ /*#__PURE__*/ jsx("div", {
144
+ className: "text-2xl font-semibold tabular-nums sm:text-3xl",
145
+ children: value
146
+ }),
147
+ delta && /*#__PURE__*/ jsx("div", {
148
+ className: "mt-1 flex items-center gap-1",
149
+ children: /*#__PURE__*/ jsx(DeltaBadge, {
150
+ delta: delta
151
+ })
152
+ }),
153
+ description && /*#__PURE__*/ jsx("p", {
154
+ className: "mt-1.5 text-xs text-muted-foreground",
155
+ children: description
156
+ }),
157
+ sparkline && /*#__PURE__*/ jsx(Sparkline, {
158
+ sparkline: sparkline
159
+ })
160
+ ]
161
+ })
162
+ ]
163
+ });
164
+ }
165
+
166
+ export { StatCard };
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ export interface StatsGridProps {
3
+ children: ReactNode;
4
+ columns?: 2 | 3 | 4;
5
+ className?: string;
6
+ }
7
+ export declare function StatsGrid({ children, columns, className }: StatsGridProps): import("react").JSX.Element;
8
+ //# sourceMappingURL=stats-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats-grid.d.ts","sourceRoot":"","sources":["../src/stats-grid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAW,EAAE,SAAc,EAAE,EAAE,cAAc,+BAQlF"}
@@ -0,0 +1,15 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ const lgColsClass = {
4
+ 2: "lg:grid-cols-2",
5
+ 3: "lg:grid-cols-3",
6
+ 4: "lg:grid-cols-4"
7
+ };
8
+ function StatsGrid({ children, columns = 4, className = "" }) {
9
+ return /*#__PURE__*/ jsx("div", {
10
+ className: `grid gap-4 grid-cols-1 sm:grid-cols-2 ${lgColsClass[columns]} ${className}`,
11
+ children: children
12
+ });
13
+ }
14
+
15
+ export { StatsGrid };
package/package.json ADDED
@@ -0,0 +1,149 @@
1
+ {
2
+ "name": "@lindaui/blocks",
3
+ "version": "0.0.2",
4
+ "description": "Composed UI sections (auth, lists, master-detail, charts) built on @lindaui/ui — importable npm package, not a copy-paste registry.",
5
+ "author": "Franco Carballar <francocarballar@gmail.com>",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/francocarballar/ts-design-system.git",
10
+ "directory": "packages/blocks"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "sideEffects": false,
16
+ "type": "module",
17
+ "exports": {
18
+ "./login-form": {
19
+ "types": "./dist/login-form.d.ts",
20
+ "import": "./dist/login-form.js"
21
+ },
22
+ "./list-item": {
23
+ "types": "./dist/list-item.d.ts",
24
+ "import": "./dist/list-item.js"
25
+ },
26
+ "./list-pane": {
27
+ "types": "./dist/list-pane.d.ts",
28
+ "import": "./dist/list-pane.js"
29
+ },
30
+ "./detail-panel": {
31
+ "types": "./dist/detail-panel.d.ts",
32
+ "import": "./dist/detail-panel.js"
33
+ },
34
+ "./confirm-dialog": {
35
+ "types": "./dist/confirm-dialog.d.ts",
36
+ "import": "./dist/confirm-dialog.js"
37
+ },
38
+ "./image-viewer": {
39
+ "types": "./dist/image-viewer.d.ts",
40
+ "import": "./dist/image-viewer.js"
41
+ },
42
+ "./split-workspace": {
43
+ "types": "./dist/split-workspace.d.ts",
44
+ "import": "./dist/split-workspace.js"
45
+ },
46
+ "./document-panel": {
47
+ "types": "./dist/document-panel.d.ts",
48
+ "import": "./dist/document-panel.js"
49
+ },
50
+ "./document-reader": {
51
+ "types": "./dist/document-reader.d.ts",
52
+ "import": "./dist/document-reader.js"
53
+ },
54
+ "./recording-overlay": {
55
+ "types": "./dist/recording-overlay.d.ts",
56
+ "import": "./dist/recording-overlay.js"
57
+ },
58
+ "./field-array-form": {
59
+ "types": "./dist/field-array-form.d.ts",
60
+ "import": "./dist/field-array-form.js"
61
+ },
62
+ "./auth-provider": {
63
+ "types": "./dist/auth-provider.d.ts",
64
+ "import": "./dist/auth-provider.js"
65
+ },
66
+ "./auth-layout": {
67
+ "types": "./dist/auth-layout.d.ts",
68
+ "import": "./dist/auth-layout.js"
69
+ },
70
+ "./area-chart": {
71
+ "types": "./dist/area-chart.d.ts",
72
+ "import": "./dist/area-chart.js"
73
+ },
74
+ "./bar-chart": {
75
+ "types": "./dist/bar-chart.d.ts",
76
+ "import": "./dist/bar-chart.js"
77
+ },
78
+ "./line-chart": {
79
+ "types": "./dist/line-chart.d.ts",
80
+ "import": "./dist/line-chart.js"
81
+ },
82
+ "./pie-chart": {
83
+ "types": "./dist/pie-chart.d.ts",
84
+ "import": "./dist/pie-chart.js"
85
+ },
86
+ "./radar-chart": {
87
+ "types": "./dist/radar-chart.d.ts",
88
+ "import": "./dist/radar-chart.js"
89
+ },
90
+ "./radial-chart": {
91
+ "types": "./dist/radial-chart.d.ts",
92
+ "import": "./dist/radial-chart.js"
93
+ },
94
+ "./stat-card": {
95
+ "types": "./dist/stat-card.d.ts",
96
+ "import": "./dist/stat-card.js"
97
+ },
98
+ "./chart-card": {
99
+ "types": "./dist/chart-card.d.ts",
100
+ "import": "./dist/chart-card.js"
101
+ },
102
+ "./stats-grid": {
103
+ "types": "./dist/stats-grid.d.ts",
104
+ "import": "./dist/stats-grid.js"
105
+ }
106
+ },
107
+ "files": [
108
+ "dist",
109
+ "LICENSE",
110
+ "README.md"
111
+ ],
112
+ "peerDependencies": {
113
+ "react": ">=19",
114
+ "react-dom": ">=19",
115
+ "react-hook-form": ">=7",
116
+ "lucide-react": ">=0.4",
117
+ "recharts": ">=3",
118
+ "@lindaui/ui": "*",
119
+ "@lindaui/tokens": "*"
120
+ },
121
+ "devDependencies": {
122
+ "bunchee": "^6.0.0",
123
+ "vitest": "^2.0.0",
124
+ "vite": "^6.4.3",
125
+ "@vitejs/plugin-react": "^4.3.0",
126
+ "@testing-library/react": "^16.0.0",
127
+ "@testing-library/user-event": "^14.5.0",
128
+ "@testing-library/jest-dom": "^6.4.0",
129
+ "jsdom": "^24.0.0",
130
+ "react": "^19.0.0",
131
+ "react-dom": "^19.0.0",
132
+ "@types/react": "^19.0.0",
133
+ "@types/react-dom": "^19.0.0",
134
+ "react-hook-form": "^7.53.0",
135
+ "lucide-react": "^0.460.0",
136
+ "recharts": "^3.9.0",
137
+ "zod": "^3.23.0",
138
+ "@hookform/resolvers": "^3.9.0",
139
+ "typescript": "^6.0.3",
140
+ "@lindaui/ui": "0.0.2",
141
+ "@lindaui/tokens": "0.0.2"
142
+ },
143
+ "scripts": {
144
+ "build": "bunchee --no-dts && tsc -p tsconfig.build.json",
145
+ "dev": "bunchee --watch",
146
+ "test": "vitest run",
147
+ "test:watch": "vitest"
148
+ }
149
+ }