@pattern-stack/frontend-patterns 0.0.3 → 0.0.4

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 (154) hide show
  1. package/dist/index.es.js +1 -1
  2. package/dist/index.js +1 -0
  3. package/package.json +5 -3
  4. package/src/App.css +42 -0
  5. package/src/App.tsx +54 -0
  6. package/src/__tests__/README.md +221 -0
  7. package/src/__tests__/atoms/hooks/simple-hooks.test.ts +44 -0
  8. package/src/__tests__/atoms/ui/button.test.tsx +68 -0
  9. package/src/__tests__/atoms/utils/simple.test.ts +18 -0
  10. package/src/__tests__/atoms/utils/utils.test.ts +77 -0
  11. package/src/__tests__/features/auth/simple-auth.test.tsx +40 -0
  12. package/src/__tests__/molecules/layout/simple-layout.test.tsx +81 -0
  13. package/src/__tests__/organisms/showcase/simple-showcase.test.tsx +167 -0
  14. package/src/__tests__/setup.ts +51 -0
  15. package/src/__tests__/utils.tsx +123 -0
  16. package/src/atoms/composed/Accordion/Accordion.tsx +271 -0
  17. package/src/atoms/composed/Accordion/index.ts +1 -0
  18. package/src/atoms/composed/Alert/Alert.tsx +132 -0
  19. package/src/atoms/composed/Alert/index.ts +1 -0
  20. package/src/atoms/composed/Breadcrumb/Breadcrumb.tsx +83 -0
  21. package/src/atoms/composed/Breadcrumb/index.ts +1 -0
  22. package/src/atoms/composed/Chart/Chart.tsx +425 -0
  23. package/src/atoms/composed/Chart/index.ts +2 -0
  24. package/src/atoms/composed/ColorSwatch/ColorSwatch.tsx +72 -0
  25. package/src/atoms/composed/ColorSwatch/index.ts +1 -0
  26. package/src/atoms/composed/DarkModeToggle.tsx +66 -0
  27. package/src/atoms/composed/DataBadge/DataBadge.tsx +81 -0
  28. package/src/atoms/composed/DataBadge/index.ts +1 -0
  29. package/src/atoms/composed/DataTable/DataTable.tsx +394 -0
  30. package/src/atoms/composed/DataTable/TableCellWithTooltip.tsx +41 -0
  31. package/src/atoms/composed/DataTable/index.ts +2 -0
  32. package/src/atoms/composed/DateTimePicker/DateTimePicker.tsx +611 -0
  33. package/src/atoms/composed/DateTimePicker/index.ts +2 -0
  34. package/src/atoms/composed/DetailedCard/DetailedCard.tsx +181 -0
  35. package/src/atoms/composed/DetailedCard/index.ts +2 -0
  36. package/src/atoms/composed/EmptyState/EmptyState.tsx +90 -0
  37. package/src/atoms/composed/EmptyState/index.ts +1 -0
  38. package/src/atoms/composed/FileUpload/FileUpload.tsx +477 -0
  39. package/src/atoms/composed/FileUpload/index.ts +2 -0
  40. package/src/atoms/composed/FormField/FormField.tsx +92 -0
  41. package/src/atoms/composed/FormField/index.ts +1 -0
  42. package/src/atoms/composed/GlobalSearch/GlobalSearch.tsx +37 -0
  43. package/src/atoms/composed/GlobalSearch/index.ts +1 -0
  44. package/src/atoms/composed/IconBadge/IconBadge.tsx +95 -0
  45. package/src/atoms/composed/IconBadge/index.ts +2 -0
  46. package/src/atoms/composed/Modal/Modal.tsx +223 -0
  47. package/src/atoms/composed/Modal/index.ts +2 -0
  48. package/src/atoms/composed/PaletteSwitcher.tsx +386 -0
  49. package/src/atoms/composed/ProgressBar/ProgressBar.tsx +116 -0
  50. package/src/atoms/composed/ProgressBar/index.ts +1 -0
  51. package/src/atoms/composed/StatCard/StatCard.tsx +219 -0
  52. package/src/atoms/composed/StatCard/index.ts +1 -0
  53. package/src/atoms/composed/StyleGuide.tsx +717 -0
  54. package/src/atoms/composed/Toast/Toast.tsx +219 -0
  55. package/src/atoms/composed/Toast/index.ts +1 -0
  56. package/src/atoms/composed/Tooltip/Tooltip.tsx +213 -0
  57. package/src/atoms/composed/Tooltip/index.ts +1 -0
  58. package/src/atoms/composed/UserAvatar/UserAvatar.tsx +139 -0
  59. package/src/atoms/composed/UserAvatar/index.ts +1 -0
  60. package/src/atoms/composed/UserMenu/UserMenu.tsx +16 -0
  61. package/src/atoms/composed/UserMenu/index.ts +1 -0
  62. package/src/atoms/composed/index.ts +29 -0
  63. package/src/atoms/hooks/useApi.ts +80 -0
  64. package/src/atoms/hooks/useHealth.ts +17 -0
  65. package/src/atoms/index.ts +13 -0
  66. package/src/atoms/services/api/client.ts +134 -0
  67. package/src/atoms/services/auth-service.ts +248 -0
  68. package/src/atoms/services/health.ts +15 -0
  69. package/src/atoms/services/index.ts +3 -0
  70. package/src/atoms/shared/config/constants.ts +17 -0
  71. package/src/atoms/shared/config/dashboard-sizes.ts +111 -0
  72. package/src/atoms/shared/config/environment.ts +10 -0
  73. package/src/atoms/shared/index.ts +4 -0
  74. package/src/atoms/shared/styles/color-palettes.css +566 -0
  75. package/src/atoms/types/auth.ts +62 -0
  76. package/src/atoms/types/generated.ts +1469 -0
  77. package/src/atoms/types/index.ts +4 -0
  78. package/src/atoms/types/loading.ts +28 -0
  79. package/src/atoms/ui/Badge.tsx +30 -0
  80. package/src/atoms/ui/ErrorBoundary.tsx +59 -0
  81. package/src/atoms/ui/Select.tsx +53 -0
  82. package/src/atoms/ui/Switch.tsx +42 -0
  83. package/src/atoms/ui/Tabs.tsx +118 -0
  84. package/src/atoms/ui/avatar.tsx +48 -0
  85. package/src/atoms/ui/button.tsx +70 -0
  86. package/src/atoms/ui/card.tsx +76 -0
  87. package/src/atoms/ui/dropdown-menu.tsx +199 -0
  88. package/src/atoms/ui/index.ts +39 -0
  89. package/src/atoms/ui/input.tsx +23 -0
  90. package/src/atoms/ui/label.tsx +23 -0
  91. package/src/atoms/ui/skeleton.tsx +13 -0
  92. package/src/atoms/ui/spinner.tsx +49 -0
  93. package/src/atoms/ui/table.tsx +116 -0
  94. package/src/atoms/utils/animations.ts +135 -0
  95. package/src/atoms/utils/tooltip-helpers.ts +140 -0
  96. package/src/atoms/utils/utils.ts +9 -0
  97. package/src/features/auth/components/LoginForm.tsx +168 -0
  98. package/src/features/auth/components/LogoutButton.tsx +19 -0
  99. package/src/features/auth/components/ProtectedRoute.tsx +60 -0
  100. package/src/features/auth/components/index.ts +4 -0
  101. package/src/features/auth/hooks/index.ts +2 -0
  102. package/src/features/auth/hooks/useAuth.tsx +205 -0
  103. package/src/features/auth/hooks/usePermissions.ts +35 -0
  104. package/src/features/auth/index.ts +2 -0
  105. package/src/features/index.ts +2 -0
  106. package/src/index.css +704 -0
  107. package/src/index.ts +13 -0
  108. package/src/main.tsx +48 -0
  109. package/src/molecules/.gitkeep +0 -0
  110. package/src/molecules/forms/FormGroup.tsx +75 -0
  111. package/src/molecules/forms/SearchInput.tsx +259 -0
  112. package/src/molecules/forms/index.ts +4 -0
  113. package/src/molecules/index.ts +4 -0
  114. package/src/molecules/layout/AppHeader/AppHeader.tsx +42 -0
  115. package/src/molecules/layout/AppHeader/index.ts +1 -0
  116. package/src/molecules/layout/AppLayout.tsx +29 -0
  117. package/src/molecules/layout/PageTemplate.tsx +87 -0
  118. package/src/molecules/layout/SectionHeader/SectionHeader.tsx +87 -0
  119. package/src/molecules/layout/SectionHeader/index.ts +1 -0
  120. package/src/molecules/layout/ShowcaseSection.tsx +57 -0
  121. package/src/molecules/layout/Sidebar.tsx +144 -0
  122. package/src/molecules/layout/SidebarButton/SidebarButton.tsx +99 -0
  123. package/src/molecules/layout/SidebarButton/index.ts +1 -0
  124. package/src/molecules/layout/SidebarContext.tsx +31 -0
  125. package/src/molecules/layout/index.ts +7 -0
  126. package/src/molecules/navigation/NavMenu.tsx +188 -0
  127. package/src/molecules/navigation/Pagination.tsx +172 -0
  128. package/src/molecules/navigation/index.ts +4 -0
  129. package/src/organisms/index.ts +5 -0
  130. package/src/organisms/showcase/ComponentShowcasePage.tsx +2496 -0
  131. package/src/organisms/showcase/index.ts +1 -0
  132. package/src/pages/AdminShowcase/AdminCRUDShowcase.tsx +242 -0
  133. package/src/pages/AdminShowcase/AdminDashboardShowcase.tsx +171 -0
  134. package/src/pages/AdminShowcase/AdminDetailShowcase.tsx +385 -0
  135. package/src/pages/AdminShowcase/index.tsx +3 -0
  136. package/src/pages/ComponentShowcase/BadgesShowcase.tsx +188 -0
  137. package/src/pages/ComponentShowcase/CardsShowcase.tsx +392 -0
  138. package/src/pages/ComponentShowcase/PalettesShowcase.tsx +207 -0
  139. package/src/pages/ComponentShowcase/StatesShowcase.tsx +485 -0
  140. package/src/pages/ComponentShowcase/TablesShowcase.tsx +134 -0
  141. package/src/pages/ComponentShowcase/TypographyShowcase.tsx +255 -0
  142. package/src/pages/ComponentShowcase/index.tsx +188 -0
  143. package/src/pages/index.ts +2 -0
  144. package/src/templates/AuthTemplate.tsx +216 -0
  145. package/src/templates/ComponentShowcaseTemplate.tsx +173 -0
  146. package/src/templates/DashboardTemplate.tsx +232 -0
  147. package/src/templates/DataTemplate.tsx +319 -0
  148. package/src/templates/admin/AdminCRUDTemplate.tsx +630 -0
  149. package/src/templates/admin/AdminDashboardTemplate.tsx +351 -0
  150. package/src/templates/admin/AdminDetailTemplate.tsx +563 -0
  151. package/src/templates/admin/index.ts +29 -0
  152. package/src/templates/factory.tsx +169 -0
  153. package/src/templates/index.ts +37 -0
  154. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,173 @@
1
+ import React from 'react';
2
+ import { Card } from '../atoms/ui/card';
3
+ import { ShowcaseSection } from '../molecules/layout';
4
+
5
+ interface PrimaryComponentSection {
6
+ title: string;
7
+ description: string;
8
+ badge: {
9
+ text: string;
10
+ variant?: 'status' | 'category';
11
+ status?: 'success' | 'warning' | 'error' | 'info' | 'neutral';
12
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
13
+ size?: 'sm' | 'md' | 'lg';
14
+ };
15
+ children: React.ReactNode;
16
+ }
17
+
18
+ interface ComposedExampleSection {
19
+ title: string;
20
+ description: string;
21
+ badge?: {
22
+ text: string;
23
+ variant?: 'status' | 'category';
24
+ status?: 'success' | 'warning' | 'error' | 'info' | 'neutral';
25
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
26
+ size?: 'sm' | 'md' | 'lg';
27
+ };
28
+ children: React.ReactNode;
29
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
30
+ }
31
+
32
+ interface ComponentShowcaseTemplateProps {
33
+ /** Category for overall theming */
34
+ category: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
35
+ /** Page title */
36
+ title: string;
37
+ /** Page description */
38
+ description: string;
39
+ /** Primary component section - core component with basic variants */
40
+ primaryComponent: PrimaryComponentSection;
41
+ /** Optional composed examples - complex usage patterns and real-world scenarios */
42
+ composedExamples?: {
43
+ title: string;
44
+ description: string;
45
+ sections: ComposedExampleSection[];
46
+ };
47
+ /** Optional ephemeral examples - inline customized components */
48
+ ephemeralExamples?: {
49
+ title: string;
50
+ description: string;
51
+ sections: ComposedExampleSection[];
52
+ };
53
+ /** Additional content that doesn't fit the primary/composed pattern */
54
+ additionalSections?: React.ReactNode;
55
+ }
56
+
57
+ export const ComponentShowcaseTemplate: React.FC<ComponentShowcaseTemplateProps> = ({
58
+ category,
59
+ title,
60
+ description,
61
+ primaryComponent,
62
+ composedExamples,
63
+ ephemeralExamples,
64
+ additionalSections
65
+ }) => {
66
+ return (
67
+ <div className="space-y-8">
68
+ {/* Page Header */}
69
+ <div className="space-y-2 mb-8">
70
+ <h2 className="text-2xl font-bold text-foreground">{title}</h2>
71
+ <p className="text-muted-foreground">{description}</p>
72
+ </div>
73
+
74
+ {/* Primary Component Section */}
75
+ <Card className="p-6" category={category}>
76
+ <ShowcaseSection
77
+ title={primaryComponent.title}
78
+ description={primaryComponent.description}
79
+ badge={primaryComponent.badge}
80
+ >
81
+ {primaryComponent.children}
82
+ </ShowcaseSection>
83
+ </Card>
84
+
85
+ {/* Composed Examples Section */}
86
+ {composedExamples && (
87
+ <div className="space-y-6">
88
+ {/* Composed Examples Header */}
89
+ <div className="space-y-2 mt-12 mb-8">
90
+ <h3 className="text-xl font-bold text-foreground">{composedExamples.title}</h3>
91
+ <p className="text-muted-foreground">{composedExamples.description}</p>
92
+ </div>
93
+
94
+ {/* Composed Example Sections */}
95
+ <div className="grid gap-6">
96
+ {composedExamples.sections.map((section, index) => (
97
+ <Card
98
+ key={index}
99
+ className="p-6"
100
+ category={section.category || category}
101
+ >
102
+ {section.badge ? (
103
+ <ShowcaseSection
104
+ title={section.title}
105
+ description={section.description}
106
+ badge={section.badge}
107
+ >
108
+ {section.children}
109
+ </ShowcaseSection>
110
+ ) : (
111
+ <div className="space-y-6">
112
+ <div className="space-y-4">
113
+ <h4 className="text-lg font-medium">{section.title}</h4>
114
+ <p className="text-sm text-muted-foreground">{section.description}</p>
115
+ </div>
116
+ <div>{section.children}</div>
117
+ </div>
118
+ )}
119
+ </Card>
120
+ ))}
121
+ </div>
122
+ </div>
123
+ )}
124
+
125
+ {/* Ephemeral Examples Section */}
126
+ {ephemeralExamples && (
127
+ <div className="space-y-6">
128
+ {/* Ephemeral Examples Header */}
129
+ <div className="space-y-2 mt-12 mb-8">
130
+ <h3 className="text-xl font-bold text-foreground">{ephemeralExamples.title}</h3>
131
+ <p className="text-muted-foreground">{ephemeralExamples.description}</p>
132
+ </div>
133
+
134
+ {/* Ephemeral Example Sections */}
135
+ <div className="grid gap-6">
136
+ {ephemeralExamples.sections.map((section, index) => (
137
+ <Card
138
+ key={index}
139
+ className="p-6"
140
+ category={section.category || category}
141
+ >
142
+ {section.badge ? (
143
+ <ShowcaseSection
144
+ title={section.title}
145
+ description={section.description}
146
+ badge={section.badge}
147
+ >
148
+ {section.children}
149
+ </ShowcaseSection>
150
+ ) : (
151
+ <div className="space-y-6">
152
+ <div className="space-y-4">
153
+ <h4 className="text-lg font-medium">{section.title}</h4>
154
+ <p className="text-sm text-muted-foreground">{section.description}</p>
155
+ </div>
156
+ <div>{section.children}</div>
157
+ </div>
158
+ )}
159
+ </Card>
160
+ ))}
161
+ </div>
162
+ </div>
163
+ )}
164
+
165
+ {/* Additional Sections */}
166
+ {additionalSections && (
167
+ <div className="space-y-6">
168
+ {additionalSections}
169
+ </div>
170
+ )}
171
+ </div>
172
+ );
173
+ };
@@ -0,0 +1,232 @@
1
+ import React from 'react';
2
+ import { cn } from '../atoms/utils/utils';
3
+ import { SectionHeader } from '../molecules/layout/SectionHeader';
4
+ import { Card } from '../atoms/ui/card';
5
+
6
+ export interface DashboardTemplateProps {
7
+ /** Page title */
8
+ title: string;
9
+ /** Page description */
10
+ description?: string;
11
+ /** Header actions */
12
+ actions?: React.ReactNode;
13
+ /** Main content */
14
+ children: React.ReactNode;
15
+ /** Additional CSS classes */
16
+ className?: string;
17
+ /** Category-based styling */
18
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
19
+ /** Whether to show breadcrumbs */
20
+ showBreadcrumbs?: boolean;
21
+ /** Breadcrumb items */
22
+ breadcrumbs?: Array<{ label: string; href?: string }>;
23
+ /** Page subtitle */
24
+ subtitle?: string;
25
+ }
26
+
27
+ export const DashboardTemplate: React.FC<DashboardTemplateProps> = ({
28
+ title,
29
+ description,
30
+ actions,
31
+ children,
32
+ className,
33
+ category = 1,
34
+ showBreadcrumbs = false,
35
+ breadcrumbs = [],
36
+ subtitle
37
+ }) => {
38
+ return (
39
+ <div className={cn('flex flex-col min-h-0 flex-1', className)}>
40
+ {/* Header Section */}
41
+ <div className="flex-shrink-0 border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
42
+ <div className="container mx-auto px-6 py-6">
43
+ {/* Breadcrumbs */}
44
+ {showBreadcrumbs && breadcrumbs.length > 0 && (
45
+ <nav className="mb-4">
46
+ <ol className="flex items-center space-x-2 text-sm">
47
+ {breadcrumbs.map((crumb, index) => {
48
+ const isLast = index === breadcrumbs.length - 1;
49
+ return (
50
+ <li key={index} className="flex items-center">
51
+ {crumb.href && !isLast ? (
52
+ <a
53
+ href={crumb.href}
54
+ className={cn(
55
+ 'text-muted-foreground hover:text-foreground transition-colors',
56
+ `hover:text-category-${category}`
57
+ )}
58
+ >
59
+ {crumb.label}
60
+ </a>
61
+ ) : (
62
+ <span className={isLast ? `text-category-${category} font-medium` : 'text-muted-foreground'}>
63
+ {crumb.label}
64
+ </span>
65
+ )}
66
+ {!isLast && (
67
+ <span className="mx-2 text-muted-foreground">/</span>
68
+ )}
69
+ </li>
70
+ );
71
+ })}
72
+ </ol>
73
+ </nav>
74
+ )}
75
+
76
+ {/* Page Header */}
77
+ <div className="flex items-start justify-between">
78
+ <div className="flex-1 min-w-0">
79
+ <SectionHeader
80
+ title={title}
81
+ description={description}
82
+ subtitle={subtitle}
83
+ size="lg"
84
+ className="text-left"
85
+ />
86
+ </div>
87
+
88
+ {actions && (
89
+ <div className="ml-6 flex-shrink-0">
90
+ {actions}
91
+ </div>
92
+ )}
93
+ </div>
94
+ </div>
95
+ </div>
96
+
97
+ {/* Main Content */}
98
+ <div className="flex-1 min-h-0 overflow-auto">
99
+ <div className="container mx-auto px-6 py-6">
100
+ {children}
101
+ </div>
102
+ </div>
103
+ </div>
104
+ );
105
+ };
106
+
107
+ /**
108
+ * Dashboard Grid Layout Component
109
+ * Provides standardized grid layouts for dashboard content
110
+ */
111
+ export interface DashboardGridProps {
112
+ /** Grid columns configuration */
113
+ columns?: 1 | 2 | 3 | 4;
114
+ /** Gap between grid items */
115
+ gap?: 'sm' | 'md' | 'lg';
116
+ /** Grid content */
117
+ children: React.ReactNode;
118
+ /** Additional CSS classes */
119
+ className?: string;
120
+ }
121
+
122
+ export const DashboardGrid: React.FC<DashboardGridProps> = ({
123
+ columns = 3,
124
+ gap = 'md',
125
+ children,
126
+ className
127
+ }) => {
128
+ const columnClasses = {
129
+ 1: 'grid-cols-1',
130
+ 2: 'grid-cols-1 lg:grid-cols-2',
131
+ 3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
132
+ 4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
133
+ };
134
+
135
+ const gapClasses = {
136
+ sm: 'gap-4',
137
+ md: 'gap-6',
138
+ lg: 'gap-8'
139
+ };
140
+
141
+ return (
142
+ <div
143
+ className={cn(
144
+ 'grid',
145
+ columnClasses[columns],
146
+ gapClasses[gap],
147
+ className
148
+ )}
149
+ data-component-name="DashboardGrid"
150
+ >
151
+ {children}
152
+ </div>
153
+ );
154
+ };
155
+
156
+ /**
157
+ * Dashboard Card Component
158
+ * Standardized card component for dashboard content
159
+ */
160
+ export interface DashboardCardProps {
161
+ /** Card title */
162
+ title?: string;
163
+ /** Card description */
164
+ description?: string;
165
+ /** Card content */
166
+ children: React.ReactNode;
167
+ /** Card actions */
168
+ actions?: React.ReactNode;
169
+ /** Additional CSS classes */
170
+ className?: string;
171
+ /** Category-based styling */
172
+ category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
173
+ /** Card padding */
174
+ padding?: 'sm' | 'md' | 'lg';
175
+ }
176
+
177
+ export const DashboardCard: React.FC<DashboardCardProps> = ({
178
+ title,
179
+ description,
180
+ children,
181
+ actions,
182
+ className,
183
+ category,
184
+ padding = 'md'
185
+ }) => {
186
+ const paddingClasses = {
187
+ sm: 'p-4',
188
+ md: 'p-6',
189
+ lg: 'p-8'
190
+ };
191
+
192
+ return (
193
+ <Card
194
+ className={cn(paddingClasses[padding], className)}
195
+ category={category}
196
+ >
197
+ {/* Card Header */}
198
+ {(title || description || actions) && (
199
+ <div className="mb-4">
200
+ <div className="flex items-start justify-between">
201
+ <div className="flex-1 min-w-0">
202
+ {title && (
203
+ <h3 className={cn(
204
+ 'text-lg font-semibold text-foreground mb-1',
205
+ category && `text-category-${category}`
206
+ )}>
207
+ {title}
208
+ </h3>
209
+ )}
210
+ {description && (
211
+ <p className="text-sm text-muted-foreground">
212
+ {description}
213
+ </p>
214
+ )}
215
+ </div>
216
+
217
+ {actions && (
218
+ <div className="ml-4 flex-shrink-0">
219
+ {actions}
220
+ </div>
221
+ )}
222
+ </div>
223
+ </div>
224
+ )}
225
+
226
+ {/* Card Content */}
227
+ <div>
228
+ {children}
229
+ </div>
230
+ </Card>
231
+ );
232
+ };