omnira-ui 0.2.0 → 0.3.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.
Files changed (29) hide show
  1. package/cli/omnira-init.mjs +197 -16
  2. package/components/ui/ActivityGauge/ActivityGauge.module.css +109 -0
  3. package/components/ui/ActivityGauge/ActivityGauge.tsx +87 -0
  4. package/components/ui/ActivityGauge/index.ts +2 -0
  5. package/components/ui/Calendar/Calendar.module.css +492 -0
  6. package/components/ui/Calendar/Calendar.tsx +445 -0
  7. package/components/ui/Calendar/config.ts +130 -0
  8. package/components/ui/Calendar/index.ts +4 -0
  9. package/components/ui/CardHeader/CardHeader.module.css +79 -0
  10. package/components/ui/CardHeader/CardHeader.tsx +45 -0
  11. package/components/ui/CardHeader/index.ts +2 -0
  12. package/components/ui/EmptyState/EmptyState.module.css +65 -0
  13. package/components/ui/EmptyState/EmptyState.tsx +37 -0
  14. package/components/ui/EmptyState/index.ts +2 -0
  15. package/components/ui/Metric/Metric.module.css +140 -0
  16. package/components/ui/Metric/Metric.tsx +78 -0
  17. package/components/ui/Metric/index.ts +2 -0
  18. package/components/ui/PageHeader/PageHeader.module.css +128 -0
  19. package/components/ui/PageHeader/PageHeader.tsx +61 -0
  20. package/components/ui/PageHeader/index.ts +2 -0
  21. package/components/ui/Table/Table.module.css +444 -0
  22. package/components/ui/Table/Table.tsx +547 -0
  23. package/components/ui/Table/customers.json +74 -0
  24. package/components/ui/Table/index.ts +14 -0
  25. package/components/ui/Table/invoices.json +92 -0
  26. package/components/ui/Table/orders.json +108 -0
  27. package/components/ui/Table/team-members.json +130 -0
  28. package/components/ui/Table/uploaded-files.json +53 -0
  29. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export { CardHeader } from "./CardHeader";
2
+ export type { CardHeaderProps } from "./CardHeader";
@@ -0,0 +1,65 @@
1
+ /* ============================================
2
+ Empty State — Glassmorphism Styles
3
+ ============================================ */
4
+
5
+ .emptyState {
6
+ display: flex;
7
+ flex-direction: column;
8
+ align-items: center;
9
+ justify-content: center;
10
+ text-align: center;
11
+ padding: 48px 32px;
12
+ border-radius: var(--radius-lg);
13
+ background: var(--color-bg-card);
14
+ border: 1px solid var(--color-border-standard);
15
+ box-shadow: var(--shadow-card);
16
+ backdrop-filter: var(--blur-standard);
17
+ }
18
+
19
+ /* ── Icon ── */
20
+
21
+ .iconWrapper {
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ width: 56px;
26
+ height: 56px;
27
+ border-radius: var(--radius-md);
28
+ background: var(--color-bg-elevated);
29
+ border: 1px solid var(--color-border-subtle);
30
+ color: var(--color-text-tertiary);
31
+ margin-bottom: 20px;
32
+ }
33
+
34
+ .iconWrapperLime {
35
+ background: var(--color-bg-lime-subtle);
36
+ border-color: var(--color-border-lime-subtle);
37
+ color: var(--color-lime);
38
+ }
39
+
40
+ /* ── Text ── */
41
+
42
+ .title {
43
+ font-family: var(--font-display);
44
+ font-size: 18px;
45
+ font-weight: 700;
46
+ color: var(--color-text-primary);
47
+ margin-bottom: 8px;
48
+ line-height: 1.3;
49
+ }
50
+
51
+ .description {
52
+ font-size: 14px;
53
+ color: var(--color-text-tertiary);
54
+ line-height: 1.5;
55
+ max-width: 360px;
56
+ margin-bottom: 24px;
57
+ }
58
+
59
+ /* ── Actions ── */
60
+
61
+ .actions {
62
+ display: flex;
63
+ align-items: center;
64
+ gap: 12px;
65
+ }
@@ -0,0 +1,37 @@
1
+ import { cn } from "@/lib/cn";
2
+ import styles from "./EmptyState.module.css";
3
+
4
+ /* ── Types ── */
5
+
6
+ export interface EmptyStateProps {
7
+ icon?: React.ReactNode;
8
+ iconAccent?: boolean;
9
+ title: string;
10
+ description?: string;
11
+ actions?: React.ReactNode;
12
+ className?: string;
13
+ }
14
+
15
+ /* ── Component ── */
16
+
17
+ export function EmptyState({
18
+ icon,
19
+ iconAccent = false,
20
+ title,
21
+ description,
22
+ actions,
23
+ className,
24
+ }: EmptyStateProps) {
25
+ return (
26
+ <div className={cn(styles.emptyState, className)}>
27
+ {icon && (
28
+ <div className={cn(styles.iconWrapper, iconAccent && styles.iconWrapperLime)}>
29
+ {icon}
30
+ </div>
31
+ )}
32
+ <h3 className={styles.title}>{title}</h3>
33
+ {description && <p className={styles.description}>{description}</p>}
34
+ {actions && <div className={styles.actions}>{actions}</div>}
35
+ </div>
36
+ );
37
+ }
@@ -0,0 +1,2 @@
1
+ export { EmptyState } from "./EmptyState";
2
+ export type { EmptyStateProps } from "./EmptyState";
@@ -0,0 +1,140 @@
1
+ /* ============================================
2
+ Metric — Glassmorphism Styles
3
+ ============================================ */
4
+
5
+ .metricCard {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 12px;
9
+ padding: 24px;
10
+ border-radius: var(--radius-lg);
11
+ background: var(--color-bg-card);
12
+ border: 1px solid var(--color-border-standard);
13
+ box-shadow: var(--shadow-card);
14
+ backdrop-filter: var(--blur-standard);
15
+ }
16
+
17
+ /* ── Header ── */
18
+
19
+ .header {
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: space-between;
23
+ }
24
+
25
+ .label {
26
+ font-size: 14px;
27
+ font-weight: 500;
28
+ color: var(--color-text-secondary);
29
+ }
30
+
31
+ .iconWrapper {
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ width: 40px;
36
+ height: 40px;
37
+ border-radius: var(--radius-md);
38
+ background: var(--color-bg-elevated);
39
+ border: 1px solid var(--color-border-subtle);
40
+ color: var(--color-text-secondary);
41
+ }
42
+
43
+ /* ── Value ── */
44
+
45
+ .valueRow {
46
+ display: flex;
47
+ align-items: baseline;
48
+ gap: 12px;
49
+ }
50
+
51
+ .value {
52
+ font-family: var(--font-display);
53
+ font-size: 30px;
54
+ font-weight: 700;
55
+ color: var(--color-text-primary);
56
+ line-height: 1;
57
+ letter-spacing: -0.5px;
58
+ }
59
+
60
+ /* ── Change indicator ── */
61
+
62
+ .change {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 4px;
66
+ padding: 2px 8px;
67
+ border-radius: var(--radius-full);
68
+ font-size: 12px;
69
+ font-weight: 600;
70
+ line-height: 1.4;
71
+ }
72
+
73
+ .changeUp {
74
+ background: var(--color-success-bg);
75
+ color: var(--color-success);
76
+ border: 1px solid var(--color-success-border);
77
+ }
78
+
79
+ .changeDown {
80
+ background: var(--color-error-bg);
81
+ color: var(--color-error);
82
+ border: 1px solid var(--color-error-border);
83
+ }
84
+
85
+ .changeArrow {
86
+ display: inline-flex;
87
+ font-size: 10px;
88
+ }
89
+
90
+ /* ── Description ── */
91
+
92
+ .description {
93
+ font-size: 13px;
94
+ color: var(--color-text-tertiary);
95
+ line-height: 1.4;
96
+ }
97
+
98
+ /* ── Progress bar ── */
99
+
100
+ .progressWrapper {
101
+ margin-top: 4px;
102
+ }
103
+
104
+ .progressTrack {
105
+ width: 100%;
106
+ height: 6px;
107
+ border-radius: var(--radius-full);
108
+ background: var(--color-bg-elevated);
109
+ overflow: hidden;
110
+ }
111
+
112
+ .progressFill {
113
+ height: 100%;
114
+ border-radius: var(--radius-full);
115
+ background: var(--gradient-progress);
116
+ transition: width 0.4s ease;
117
+ }
118
+
119
+ .progressLabel {
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: space-between;
123
+ margin-top: 6px;
124
+ font-size: 12px;
125
+ color: var(--color-text-tertiary);
126
+ }
127
+
128
+ /* ── Sparkline ── */
129
+
130
+ .sparkline {
131
+ margin-top: 4px;
132
+ }
133
+
134
+ /* ── Grid layout for demos ── */
135
+
136
+ .metricGrid {
137
+ display: grid;
138
+ grid-template-columns: repeat(4, 1fr);
139
+ gap: 16px;
140
+ }
@@ -0,0 +1,78 @@
1
+ import { cn } from "@/lib/cn";
2
+ import styles from "./Metric.module.css";
3
+
4
+ /* ── Types ── */
5
+
6
+ export interface MetricProps {
7
+ label: string;
8
+ value: string;
9
+ change?: {
10
+ value: string;
11
+ direction: "up" | "down";
12
+ };
13
+ description?: string;
14
+ icon?: React.ReactNode;
15
+ progress?: {
16
+ value: number;
17
+ label?: string;
18
+ max?: string;
19
+ };
20
+ className?: string;
21
+ }
22
+
23
+ /* ── Component ── */
24
+
25
+ export function Metric({
26
+ label,
27
+ value,
28
+ change,
29
+ description,
30
+ icon,
31
+ progress,
32
+ className,
33
+ }: MetricProps) {
34
+ return (
35
+ <div className={cn(styles.metricCard, className)}>
36
+ <div className={styles.header}>
37
+ <span className={styles.label}>{label}</span>
38
+ {icon && <div className={styles.iconWrapper}>{icon}</div>}
39
+ </div>
40
+
41
+ <div className={styles.valueRow}>
42
+ <span className={styles.value}>{value}</span>
43
+ {change && (
44
+ <span
45
+ className={cn(
46
+ styles.change,
47
+ change.direction === "up" ? styles.changeUp : styles.changeDown,
48
+ )}
49
+ >
50
+ <span className={styles.changeArrow}>
51
+ {change.direction === "up" ? "↑" : "↓"}
52
+ </span>
53
+ {change.value}
54
+ </span>
55
+ )}
56
+ </div>
57
+
58
+ {description && <p className={styles.description}>{description}</p>}
59
+
60
+ {progress && (
61
+ <div className={styles.progressWrapper}>
62
+ <div className={styles.progressTrack}>
63
+ <div
64
+ className={styles.progressFill}
65
+ style={{ width: `${Math.min(progress.value, 100)}%` }}
66
+ />
67
+ </div>
68
+ {(progress.label || progress.max) && (
69
+ <div className={styles.progressLabel}>
70
+ <span>{progress.label ?? `${progress.value}%`}</span>
71
+ {progress.max && <span>{progress.max}</span>}
72
+ </div>
73
+ )}
74
+ </div>
75
+ )}
76
+ </div>
77
+ );
78
+ }
@@ -0,0 +1,2 @@
1
+ export { Metric } from "./Metric";
2
+ export type { MetricProps } from "./Metric";
@@ -0,0 +1,128 @@
1
+ /* ============================================
2
+ Page Header — Glassmorphism Styles
3
+ ============================================ */
4
+
5
+ .pageHeader {
6
+ display: flex;
7
+ align-items: flex-start;
8
+ justify-content: space-between;
9
+ gap: 24px;
10
+ padding: 24px;
11
+ border-radius: var(--radius-lg);
12
+ background: var(--color-bg-card);
13
+ border: 1px solid var(--color-border-standard);
14
+ box-shadow: var(--shadow-card);
15
+ backdrop-filter: var(--blur-standard);
16
+ }
17
+
18
+ /* ── Left content ── */
19
+
20
+ .content {
21
+ display: flex;
22
+ flex-direction: column;
23
+ gap: 4px;
24
+ min-width: 0;
25
+ }
26
+
27
+ .breadcrumbs {
28
+ display: flex;
29
+ align-items: center;
30
+ gap: 8px;
31
+ margin-bottom: 8px;
32
+ font-size: 13px;
33
+ color: var(--color-text-tertiary);
34
+ }
35
+
36
+ .breadcrumbLink {
37
+ color: var(--color-text-tertiary);
38
+ text-decoration: none;
39
+ transition: color 0.15s ease;
40
+ cursor: pointer;
41
+ }
42
+
43
+ .breadcrumbLink:hover {
44
+ color: var(--color-text-primary);
45
+ }
46
+
47
+ .breadcrumbSeparator {
48
+ color: var(--color-text-tertiary);
49
+ opacity: 0.5;
50
+ font-size: 12px;
51
+ }
52
+
53
+ .breadcrumbCurrent {
54
+ color: var(--color-text-secondary);
55
+ font-weight: 500;
56
+ }
57
+
58
+ .titleRow {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 12px;
62
+ }
63
+
64
+ .title {
65
+ font-family: var(--font-display);
66
+ font-size: 24px;
67
+ font-weight: 700;
68
+ color: var(--color-text-primary);
69
+ line-height: 1.2;
70
+ }
71
+
72
+ .description {
73
+ font-size: 14px;
74
+ color: var(--color-text-tertiary);
75
+ line-height: 1.5;
76
+ max-width: 560px;
77
+ }
78
+
79
+ /* ── Right actions ── */
80
+
81
+ .actions {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 12px;
85
+ flex-shrink: 0;
86
+ }
87
+
88
+ /* ── Tabs variant ── */
89
+
90
+ .tabsWrapper {
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 4px;
94
+ margin-top: 16px;
95
+ border-top: 1px solid var(--color-border-subtle);
96
+ padding-top: 16px;
97
+ }
98
+
99
+ .tab {
100
+ padding: 6px 16px;
101
+ border-radius: var(--radius-full);
102
+ border: none;
103
+ background: transparent;
104
+ color: var(--color-text-tertiary);
105
+ font-size: 13px;
106
+ font-weight: 500;
107
+ cursor: pointer;
108
+ transition: color 0.15s ease, background 0.2s ease;
109
+ outline: none;
110
+ font-family: inherit;
111
+ }
112
+
113
+ .tab:hover {
114
+ color: var(--color-text-secondary);
115
+ }
116
+
117
+ .tabActive {
118
+ background: var(--color-bg-elevated);
119
+ color: var(--color-text-primary);
120
+ font-weight: 600;
121
+ }
122
+
123
+ /* ── With divider ── */
124
+
125
+ .withDivider {
126
+ border-bottom: 1px solid var(--color-border-subtle);
127
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
128
+ }
@@ -0,0 +1,61 @@
1
+ import { cn } from "@/lib/cn";
2
+ import styles from "./PageHeader.module.css";
3
+
4
+ /* ── Types ── */
5
+
6
+ export interface PageHeaderBreadcrumb {
7
+ label: string;
8
+ href?: string;
9
+ }
10
+
11
+ export interface PageHeaderProps {
12
+ title: string;
13
+ description?: string;
14
+ breadcrumbs?: PageHeaderBreadcrumb[];
15
+ badge?: React.ReactNode;
16
+ actions?: React.ReactNode;
17
+ tabs?: React.ReactNode;
18
+ className?: string;
19
+ }
20
+
21
+ /* ── Component ── */
22
+
23
+ export function PageHeader({
24
+ title,
25
+ description,
26
+ breadcrumbs,
27
+ badge,
28
+ actions,
29
+ tabs,
30
+ className,
31
+ }: PageHeaderProps) {
32
+ return (
33
+ <div className={cn(styles.pageHeader, className)}>
34
+ <div className={styles.content}>
35
+ {breadcrumbs && breadcrumbs.length > 0 && (
36
+ <nav className={styles.breadcrumbs}>
37
+ {breadcrumbs.map((crumb, i) => (
38
+ <span key={i}>
39
+ {i > 0 && <span className={styles.breadcrumbSeparator}> / </span>}
40
+ {crumb.href ? (
41
+ <a href={crumb.href} className={styles.breadcrumbLink}>
42
+ {crumb.label}
43
+ </a>
44
+ ) : (
45
+ <span className={styles.breadcrumbCurrent}>{crumb.label}</span>
46
+ )}
47
+ </span>
48
+ ))}
49
+ </nav>
50
+ )}
51
+ <div className={styles.titleRow}>
52
+ <h1 className={styles.title}>{title}</h1>
53
+ {badge}
54
+ </div>
55
+ {description && <p className={styles.description}>{description}</p>}
56
+ {tabs && <div className={styles.tabsWrapper}>{tabs}</div>}
57
+ </div>
58
+ {actions && <div className={styles.actions}>{actions}</div>}
59
+ </div>
60
+ );
61
+ }
@@ -0,0 +1,2 @@
1
+ export { PageHeader } from "./PageHeader";
2
+ export type { PageHeaderProps, PageHeaderBreadcrumb } from "./PageHeader";