@zoyth/simple-site-framework 1.0.0
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/LICENSE +21 -0
- package/README.md +572 -0
- package/bin/create-simple-site.js +390 -0
- package/bin/simple-site.js +664 -0
- package/dist/client.js +135 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +107 -0
- package/dist/client.mjs.map +1 -0
- package/dist/components/index.d.mts +3936 -0
- package/dist/components/index.d.ts +3936 -0
- package/dist/components/index.js +38265 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +38173 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/index.d.mts +298 -0
- package/dist/config/index.d.ts +298 -0
- package/dist/config/index.js +19 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +1 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/index.d.mts +2184 -0
- package/dist/index.d.ts +2184 -0
- package/dist/index.js +1713 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1605 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/i18n/index.js +665 -0
- package/dist/lib/i18n/index.js.map +1 -0
- package/dist/lib/i18n/index.mjs +621 -0
- package/dist/lib/i18n/index.mjs.map +1 -0
- package/docs/DOCUMENTATION-STRUCTURE.md +1156 -0
- package/docs/EXPORTS.md +125 -0
- package/docs/PERFORMANCE.md +757 -0
- package/docs/POLICY-PAGES.md +867 -0
- package/docs/ROADMAP.md +334 -0
- package/docs/SEO.md +455 -0
- package/docs/SITEMAP.md +708 -0
- package/docs/STRUCTURED-DATA.md +671 -0
- package/docs/accessibility/common-patterns.md +529 -0
- package/docs/accessibility/keyboard-navigation.md +263 -0
- package/docs/accessibility/overview.md +122 -0
- package/docs/accessibility/screen-readers.md +311 -0
- package/docs/accessibility/wcag-compliance.md +159 -0
- package/docs/api/README.md +164 -0
- package/docs/api/components/Accessibility.md +356 -0
- package/docs/api/components/Button.md +240 -0
- package/docs/api/components/HeroSection.md +306 -0
- package/docs/architecture/decisions.md +449 -0
- package/docs/components/AnalyticsTracker.md +58 -0
- package/docs/components/AnimatedCounter.md +48 -0
- package/docs/components/AnimatedSection.md +56 -0
- package/docs/components/BlogCard.md +42 -0
- package/docs/components/Checkbox.md +56 -0
- package/docs/components/CodeBlock.md +52 -0
- package/docs/components/ComparisonTable.md +40 -0
- package/docs/components/ComponentDemo.md +38 -0
- package/docs/components/CountdownTimer.md +51 -0
- package/docs/components/ExitIntentModal.md +56 -0
- package/docs/components/FAQAccordion.md +66 -0
- package/docs/components/FeaturesGrid.md +55 -0
- package/docs/components/FileUpload.md +54 -0
- package/docs/components/I18nMetaTags.md +55 -0
- package/docs/components/Icon.md +53 -0
- package/docs/components/LazySection.md +46 -0
- package/docs/components/LiveProof.md +53 -0
- package/docs/components/LoadingSpinner.md +46 -0
- package/docs/components/MultiStepForm.md +48 -0
- package/docs/components/PolicyLayout.md +55 -0
- package/docs/components/PricingTable.md +49 -0
- package/docs/components/Radio.md +59 -0
- package/docs/components/SEOMetaTags.md +58 -0
- package/docs/components/ScriptInjector.md +50 -0
- package/docs/components/Select.md +72 -0
- package/docs/components/Skeleton.md +47 -0
- package/docs/components/StatsSection.md +48 -0
- package/docs/components/StickyBar.md +62 -0
- package/docs/components/StructuredData.md +99 -0
- package/docs/components/StyleGuide.md +46 -0
- package/docs/components/TableOfContents.md +47 -0
- package/docs/components/TestimonialCarousel.md +42 -0
- package/docs/components/Timeline.md +51 -0
- package/docs/components/Toast.md +59 -0
- package/docs/components/TrackedLink.md +62 -0
- package/docs/components/TrustBadges.md +44 -0
- package/docs/components/conversion/MobileCTA.md +363 -0
- package/docs/components/forms/ContactForm.md +75 -0
- package/docs/components/forms/FormField.md +74 -0
- package/docs/components/layout/Footer.md +601 -0
- package/docs/components/layout/Header.md +549 -0
- package/docs/components/layout/LanguageSelector.md +54 -0
- package/docs/components/layout/LanguageSwitcher.md +24 -0
- package/docs/components/overview.md +447 -0
- package/docs/components/sections/AboutSection.md +48 -0
- package/docs/components/sections/CTASection.md +596 -0
- package/docs/components/sections/CaseStudySection.md +47 -0
- package/docs/components/sections/ContactSection.md +599 -0
- package/docs/components/sections/FeatureSection.md +44 -0
- package/docs/components/sections/HeroSection.md +404 -0
- package/docs/components/sections/LogosSection.md +47 -0
- package/docs/components/sections/PersonalTaxesSection.md +23 -0
- package/docs/components/sections/RecruitingSection.md +23 -0
- package/docs/components/sections/SecurePortalSection.md +23 -0
- package/docs/components/sections/ServicePageLayout.md +52 -0
- package/docs/components/sections/ServicesSection.md +49 -0
- package/docs/components/sections/TestimonialSection.md +44 -0
- package/docs/components/sections/WhyChooseUsSection.md +54 -0
- package/docs/components/ui/Breadcrumb.md +70 -0
- package/docs/components/ui/Button.md +514 -0
- package/docs/components/ui/Card.md +501 -0
- package/docs/components/ui/Input.md +54 -0
- package/docs/components/ui/MobileLinks.md +43 -0
- package/docs/components/ui/Modal.md +60 -0
- package/docs/components/ui/Tabs.md +62 -0
- package/docs/components/ui/Textarea.md +52 -0
- package/docs/core-concepts/configuration-driven.md +552 -0
- package/docs/core-concepts/overview.md +351 -0
- package/docs/features/accessibility/README.md +73 -0
- package/docs/features/accessibility/aria-support.md +177 -0
- package/docs/features/accessibility/color-contrast.md +155 -0
- package/docs/features/accessibility/focus-management.md +187 -0
- package/docs/features/accessibility/testing.md +196 -0
- package/docs/features/analytics/README.md +51 -0
- package/docs/features/analytics/ab-testing.md +171 -0
- package/docs/features/analytics/conversion-tracking.md +207 -0
- package/docs/features/analytics/custom-events.md +219 -0
- package/docs/features/analytics/privacy.md +198 -0
- package/docs/features/analytics/setup.md +114 -0
- package/docs/features/analytics/tracking-events.md +224 -0
- package/docs/features/i18n/README.md +51 -0
- package/docs/features/i18n/best-practices.md +273 -0
- package/docs/features/i18n/configuration.md +84 -0
- package/docs/features/i18n/formatting.md +133 -0
- package/docs/features/i18n/locale-detection.md +122 -0
- package/docs/features/i18n/routing.md +99 -0
- package/docs/features/i18n/rtl-support.md +191 -0
- package/docs/features/i18n/translations.md +129 -0
- package/docs/features/internationalization.md +595 -0
- package/docs/features/performance/README.md +77 -0
- package/docs/features/performance/bundle-size.md +134 -0
- package/docs/features/performance/caching.md +131 -0
- package/docs/features/performance/code-splitting.md +121 -0
- package/docs/features/performance/image-optimization.md +110 -0
- package/docs/features/performance/lazy-loading.md +92 -0
- package/docs/features/performance/monitoring.md +148 -0
- package/docs/features/seo/README.md +51 -0
- package/docs/features/seo/best-practices.md +184 -0
- package/docs/features/seo/canonical-urls.md +182 -0
- package/docs/features/seo/meta-tags.md +126 -0
- package/docs/features/seo/open-graph.md +166 -0
- package/docs/features/seo/robots-txt.md +146 -0
- package/docs/features/seo/sitemaps.md +162 -0
- package/docs/features/seo/structured-data.md +166 -0
- package/docs/getting-started/installation.md +292 -0
- package/docs/getting-started/introduction.md +195 -0
- package/docs/getting-started/quick-start.md +460 -0
- package/docs/guides/analytics-setup.md +616 -0
- package/docs/i18n/CONFIGURATION.md +353 -0
- package/docs/i18n/EXAMPLES.md +402 -0
- package/docs/i18n/MIGRATION.md +260 -0
- package/docs/i18n/SEO.md +392 -0
- package/docs/i18n/STATIC-GENERATION-FIX.md +71 -0
- package/docs/migration/changelog.md +136 -0
- package/docs/migration/overview.md +233 -0
- package/docs/recipes/adding-animations.md +475 -0
- package/docs/recipes/forms-with-validation.md +393 -0
- package/package.json +152 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
Container component with shadow, border, and padding. The fundamental building block for content organization and layout.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Card } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component (default export)
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Card>
|
|
17
|
+
<h3>Card Title</h3>
|
|
18
|
+
<p>Card content goes here.</p>
|
|
19
|
+
</Card>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Props
|
|
23
|
+
|
|
24
|
+
### Optional Props
|
|
25
|
+
|
|
26
|
+
| Prop | Type | Default | Description |
|
|
27
|
+
|------|------|---------|-------------|
|
|
28
|
+
| `variant` | `'default' \| 'bordered' \| 'elevated'` | `'default'` | Card style variant |
|
|
29
|
+
| `padding` | `'none' \| 'sm' \| 'md' \| 'lg'` | `'md'` | Internal padding |
|
|
30
|
+
| `hoverable` | `boolean` | `false` | Add hover effect |
|
|
31
|
+
| `clickable` | `boolean` | `false` | Make card clickable |
|
|
32
|
+
| `onClick` | `() => void` | - | Click handler |
|
|
33
|
+
| `className` | `string` | - | Custom CSS classes |
|
|
34
|
+
| `children` | `ReactNode` | - | Card content |
|
|
35
|
+
|
|
36
|
+
## Variants
|
|
37
|
+
|
|
38
|
+
### Default
|
|
39
|
+
|
|
40
|
+
Subtle shadow, no border:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
<Card variant="default">
|
|
44
|
+
<h3>Default Card</h3>
|
|
45
|
+
<p>Clean and minimal appearance.</p>
|
|
46
|
+
</Card>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Bordered
|
|
50
|
+
|
|
51
|
+
Border with light shadow:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
<Card variant="bordered">
|
|
55
|
+
<h3>Bordered Card</h3>
|
|
56
|
+
<p>Clear visual separation.</p>
|
|
57
|
+
</Card>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Elevated
|
|
61
|
+
|
|
62
|
+
Pronounced shadow for depth:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
<Card variant="elevated">
|
|
66
|
+
<h3>Elevated Card</h3>
|
|
67
|
+
<p>Prominent visual hierarchy.</p>
|
|
68
|
+
</Card>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Padding
|
|
72
|
+
|
|
73
|
+
### None
|
|
74
|
+
|
|
75
|
+
No internal padding:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
<Card padding="none">
|
|
79
|
+
<img src="/image.jpg" alt="Full bleed image" />
|
|
80
|
+
<div className="p-6">
|
|
81
|
+
<h3>Image Card</h3>
|
|
82
|
+
</div>
|
|
83
|
+
</Card>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Small
|
|
87
|
+
|
|
88
|
+
Compact padding:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
<Card padding="sm">
|
|
92
|
+
<h3>Compact Card</h3>
|
|
93
|
+
</Card>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Medium (Default)
|
|
97
|
+
|
|
98
|
+
Standard padding:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
<Card padding="md">
|
|
102
|
+
<h3>Standard Card</h3>
|
|
103
|
+
</Card>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Large
|
|
107
|
+
|
|
108
|
+
Spacious padding:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
<Card padding="lg">
|
|
112
|
+
<h3>Spacious Card</h3>
|
|
113
|
+
</Card>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Examples
|
|
117
|
+
|
|
118
|
+
### Content Card
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
<Card>
|
|
122
|
+
<h3 className="text-xl font-bold mb-2">
|
|
123
|
+
Feature Title
|
|
124
|
+
</h3>
|
|
125
|
+
<p className="text-gray-600">
|
|
126
|
+
Description of the feature and its benefits.
|
|
127
|
+
</p>
|
|
128
|
+
</Card>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Clickable Card
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
<Card
|
|
135
|
+
clickable
|
|
136
|
+
hoverable
|
|
137
|
+
onClick={() => router.push('/details')}
|
|
138
|
+
>
|
|
139
|
+
<h3>Click Me</h3>
|
|
140
|
+
<p>This entire card is clickable.</p>
|
|
141
|
+
</Card>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Image Card
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
<Card padding="none">
|
|
148
|
+
<img
|
|
149
|
+
src="/product.jpg"
|
|
150
|
+
alt="Product"
|
|
151
|
+
className="w-full h-48 object-cover rounded-t-lg"
|
|
152
|
+
/>
|
|
153
|
+
<div className="p-6">
|
|
154
|
+
<h3 className="text-xl font-bold">Product Name</h3>
|
|
155
|
+
<p className="text-gray-600 mt-2">$99.99</p>
|
|
156
|
+
</div>
|
|
157
|
+
</Card>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Stat Card
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
<Card variant="bordered" className="text-center">
|
|
164
|
+
<p className="text-4xl font-bold text-primary">10K+</p>
|
|
165
|
+
<p className="text-gray-600 mt-2">Happy Customers</p>
|
|
166
|
+
</Card>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Card Grid
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
173
|
+
<Card>
|
|
174
|
+
<h3>Feature 1</h3>
|
|
175
|
+
<p>Description...</p>
|
|
176
|
+
</Card>
|
|
177
|
+
<Card>
|
|
178
|
+
<h3>Feature 2</h3>
|
|
179
|
+
<p>Description...</p>
|
|
180
|
+
</Card>
|
|
181
|
+
<Card>
|
|
182
|
+
<h3>Feature 3</h3>
|
|
183
|
+
<p>Description...</p>
|
|
184
|
+
</Card>
|
|
185
|
+
</div>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Pricing Card
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
<Card variant="elevated" className="text-center">
|
|
192
|
+
<h3 className="text-2xl font-bold">Pro Plan</h3>
|
|
193
|
+
<p className="text-4xl font-bold text-primary my-4">
|
|
194
|
+
$99<span className="text-base text-gray-600">/month</span>
|
|
195
|
+
</p>
|
|
196
|
+
<ul className="text-left space-y-2 mb-6">
|
|
197
|
+
<li>✓ Unlimited projects</li>
|
|
198
|
+
<li>✓ Priority support</li>
|
|
199
|
+
<li>✓ Advanced analytics</li>
|
|
200
|
+
</ul>
|
|
201
|
+
<Button variant="filled" className="w-full">
|
|
202
|
+
Get Started
|
|
203
|
+
</Button>
|
|
204
|
+
</Card>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Testimonial Card
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
<Card variant="bordered">
|
|
211
|
+
<p className="text-gray-700 italic mb-4">
|
|
212
|
+
"This product transformed our workflow. Highly recommended!"
|
|
213
|
+
</p>
|
|
214
|
+
<div className="flex items-center gap-4">
|
|
215
|
+
<img
|
|
216
|
+
src="/avatar.jpg"
|
|
217
|
+
alt="Jane Doe"
|
|
218
|
+
className="w-12 h-12 rounded-full"
|
|
219
|
+
/>
|
|
220
|
+
<div>
|
|
221
|
+
<p className="font-bold">Jane Doe</p>
|
|
222
|
+
<p className="text-sm text-gray-600">CEO, Company Inc</p>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</Card>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Link Card
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
<Link href="/article/1">
|
|
232
|
+
<Card hoverable className="cursor-pointer">
|
|
233
|
+
<h3 className="text-xl font-bold">Article Title</h3>
|
|
234
|
+
<p className="text-gray-600 mt-2">Article excerpt...</p>
|
|
235
|
+
<p className="text-primary mt-4">Read more →</p>
|
|
236
|
+
</Card>
|
|
237
|
+
</Link>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Styling
|
|
241
|
+
|
|
242
|
+
### Custom Background
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
<Card className="bg-gradient-to-br from-blue-50 to-indigo-100">
|
|
246
|
+
<h3>Gradient Background</h3>
|
|
247
|
+
</Card>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Custom Shadow
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
<Card className="shadow-2xl">
|
|
254
|
+
<h3>Extra Shadow</h3>
|
|
255
|
+
</Card>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Custom Rounded Corners
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
<Card className="rounded-2xl">
|
|
262
|
+
<h3>More Rounded</h3>
|
|
263
|
+
</Card>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Dark Mode
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
<Card className="dark:bg-gray-800 dark:text-white">
|
|
270
|
+
<h3>Dark Mode Card</h3>
|
|
271
|
+
</Card>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Accessibility
|
|
275
|
+
|
|
276
|
+
Card includes:
|
|
277
|
+
|
|
278
|
+
- ✅ Semantic HTML (uses `<div>` but accepts semantic tags via `as` prop)
|
|
279
|
+
- ✅ Keyboard accessible when clickable
|
|
280
|
+
- ✅ Focus visible states for interactive cards
|
|
281
|
+
- ✅ Proper contrast ratios
|
|
282
|
+
- ✅ Screen reader friendly
|
|
283
|
+
|
|
284
|
+
### Clickable Card Accessibility
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
<Card
|
|
288
|
+
clickable
|
|
289
|
+
onClick={handleClick}
|
|
290
|
+
role="button"
|
|
291
|
+
tabIndex={0}
|
|
292
|
+
onKeyDown={(e) => {
|
|
293
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
294
|
+
handleClick();
|
|
295
|
+
}
|
|
296
|
+
}}
|
|
297
|
+
>
|
|
298
|
+
<h3>Accessible Clickable Card</h3>
|
|
299
|
+
</Card>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Semantic Card
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
<Card as="article">
|
|
306
|
+
<h2>Article Title</h2>
|
|
307
|
+
<p>Article content...</p>
|
|
308
|
+
</Card>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Common Patterns
|
|
312
|
+
|
|
313
|
+
### Feature Grid
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
317
|
+
{features.map(feature => (
|
|
318
|
+
<Card key={feature.id} variant="bordered">
|
|
319
|
+
<div className="text-primary text-4xl mb-4">
|
|
320
|
+
{feature.icon}
|
|
321
|
+
</div>
|
|
322
|
+
<h3 className="text-xl font-bold mb-2">
|
|
323
|
+
{feature.title}
|
|
324
|
+
</h3>
|
|
325
|
+
<p className="text-gray-600">
|
|
326
|
+
{feature.description}
|
|
327
|
+
</p>
|
|
328
|
+
</Card>
|
|
329
|
+
))}
|
|
330
|
+
</div>
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Blog Post Preview
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
<Card hoverable padding="none">
|
|
337
|
+
<img
|
|
338
|
+
src={post.image}
|
|
339
|
+
alt={post.title}
|
|
340
|
+
className="w-full h-48 object-cover"
|
|
341
|
+
/>
|
|
342
|
+
<div className="p-6">
|
|
343
|
+
<div className="flex gap-2 mb-2">
|
|
344
|
+
{post.tags.map(tag => (
|
|
345
|
+
<span key={tag} className="text-xs bg-gray-100 px-2 py-1 rounded">
|
|
346
|
+
{tag}
|
|
347
|
+
</span>
|
|
348
|
+
))}
|
|
349
|
+
</div>
|
|
350
|
+
<h3 className="text-xl font-bold mb-2">{post.title}</h3>
|
|
351
|
+
<p className="text-gray-600 mb-4">{post.excerpt}</p>
|
|
352
|
+
<div className="flex items-center justify-between">
|
|
353
|
+
<span className="text-sm text-gray-500">{post.date}</span>
|
|
354
|
+
<Link href={`/blog/${post.slug}`} className="text-primary">
|
|
355
|
+
Read more →
|
|
356
|
+
</Link>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
</Card>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Dashboard Widget
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
<Card variant="elevated">
|
|
366
|
+
<div className="flex items-center justify-between mb-4">
|
|
367
|
+
<h3 className="text-lg font-bold">Revenue</h3>
|
|
368
|
+
<span className="text-green-600 text-sm">↑ 12%</span>
|
|
369
|
+
</div>
|
|
370
|
+
<p className="text-3xl font-bold">$45,231</p>
|
|
371
|
+
<p className="text-sm text-gray-600 mt-2">This month</p>
|
|
372
|
+
</Card>
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Team Member Card
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
<Card variant="bordered" className="text-center">
|
|
379
|
+
<img
|
|
380
|
+
src={member.avatar}
|
|
381
|
+
alt={member.name}
|
|
382
|
+
className="w-24 h-24 rounded-full mx-auto mb-4"
|
|
383
|
+
/>
|
|
384
|
+
<h3 className="text-xl font-bold">{member.name}</h3>
|
|
385
|
+
<p className="text-gray-600">{member.role}</p>
|
|
386
|
+
<div className="flex gap-4 justify-center mt-4">
|
|
387
|
+
<a href={member.linkedin} className="text-primary">
|
|
388
|
+
LinkedIn
|
|
389
|
+
</a>
|
|
390
|
+
<a href={member.twitter} className="text-primary">
|
|
391
|
+
Twitter
|
|
392
|
+
</a>
|
|
393
|
+
</div>
|
|
394
|
+
</Card>
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Layout Patterns
|
|
398
|
+
|
|
399
|
+
### Responsive Grid
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
|
403
|
+
{items.map(item => (
|
|
404
|
+
<Card key={item.id}>
|
|
405
|
+
{/* card content */}
|
|
406
|
+
</Card>
|
|
407
|
+
))}
|
|
408
|
+
</div>
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Masonry Layout
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
<div className="columns-1 md:columns-2 lg:columns-3 gap-6">
|
|
415
|
+
{items.map(item => (
|
|
416
|
+
<Card key={item.id} className="mb-6 break-inside-avoid">
|
|
417
|
+
{/* card content */}
|
|
418
|
+
</Card>
|
|
419
|
+
))}
|
|
420
|
+
</div>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Horizontal Scroll
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
<div className="flex gap-6 overflow-x-auto pb-4">
|
|
427
|
+
{items.map(item => (
|
|
428
|
+
<Card key={item.id} className="flex-shrink-0 w-80">
|
|
429
|
+
{/* card content */}
|
|
430
|
+
</Card>
|
|
431
|
+
))}
|
|
432
|
+
</div>
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## Best Practices
|
|
436
|
+
|
|
437
|
+
### ✅ Do
|
|
438
|
+
|
|
439
|
+
- Use consistent variants across similar content types
|
|
440
|
+
- Provide sufficient padding for readability
|
|
441
|
+
- Use hoverable for interactive cards
|
|
442
|
+
- Keep card content focused and scannable
|
|
443
|
+
- Use appropriate spacing between cards
|
|
444
|
+
- Consider mobile layout when designing grids
|
|
445
|
+
|
|
446
|
+
### ❌ Don't
|
|
447
|
+
|
|
448
|
+
- Nest cards too deeply
|
|
449
|
+
- Mix too many variants on the same page
|
|
450
|
+
- Make cards too small (hard to read/click)
|
|
451
|
+
- Use overly complex layouts inside cards
|
|
452
|
+
- Forget to handle empty states
|
|
453
|
+
- Make entire large sections clickable (accessibility issue)
|
|
454
|
+
|
|
455
|
+
## Performance
|
|
456
|
+
|
|
457
|
+
- Cards are server components by default
|
|
458
|
+
- No JavaScript unless using clickable/hoverable features
|
|
459
|
+
- Efficient rendering for large grids
|
|
460
|
+
- No layout shift with proper dimensions
|
|
461
|
+
|
|
462
|
+
## Troubleshooting
|
|
463
|
+
|
|
464
|
+
### Cards not displaying shadow
|
|
465
|
+
|
|
466
|
+
**Check:**
|
|
467
|
+
1. Variant is set (default has subtle shadow)
|
|
468
|
+
2. Background is not the same color as shadow
|
|
469
|
+
3. No CSS overriding shadow styles
|
|
470
|
+
|
|
471
|
+
### Hover effect not working
|
|
472
|
+
|
|
473
|
+
**Check:**
|
|
474
|
+
1. `hoverable` prop is set to `true`
|
|
475
|
+
2. Browser supports CSS transitions
|
|
476
|
+
3. No conflicting CSS
|
|
477
|
+
|
|
478
|
+
### Click handler not firing
|
|
479
|
+
|
|
480
|
+
**Check:**
|
|
481
|
+
1. `clickable` prop is set to `true`
|
|
482
|
+
2. `onClick` function is provided
|
|
483
|
+
3. No overlay blocking clicks
|
|
484
|
+
4. Card is not disabled
|
|
485
|
+
|
|
486
|
+
### Grid layout breaking on mobile
|
|
487
|
+
|
|
488
|
+
**Check:**
|
|
489
|
+
1. Using responsive grid classes (`grid-cols-1 md:grid-cols-2`)
|
|
490
|
+
2. Card min-width not too large
|
|
491
|
+
3. Gap is appropriate for mobile
|
|
492
|
+
|
|
493
|
+
## Related Components
|
|
494
|
+
|
|
495
|
+
- **[Button](./Button.md)** - Often used inside cards
|
|
496
|
+
- **[FeaturesGrid](../utilities/FeaturesGrid.md)** - Grid of feature cards
|
|
497
|
+
- **[Modal](./Modal.md)** - Card-like dialog component
|
|
498
|
+
|
|
499
|
+
## API Reference
|
|
500
|
+
|
|
501
|
+
Full TypeScript definitions: **[API Reference](../../api/components.md#card)**
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
Text input component with validation states and accessibility features.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Input } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Input
|
|
17
|
+
name="email"
|
|
18
|
+
type="email"
|
|
19
|
+
placeholder="Enter your email"
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Props
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Required | Description |
|
|
26
|
+
|------|------|----------|-------------|
|
|
27
|
+
| `name` | `string` | Yes | Input name |
|
|
28
|
+
| `type` | `string` | No | Input type (text, email, tel, etc.) |
|
|
29
|
+
| `placeholder` | `string` | No | Placeholder text |
|
|
30
|
+
| `value` | `string` | No | Input value |
|
|
31
|
+
| `defaultValue` | `string` | No | Default value |
|
|
32
|
+
| `disabled` | `boolean` | No | Disable input |
|
|
33
|
+
| `required` | `boolean` | No | Mark as required |
|
|
34
|
+
| `className` | `string` | No | Custom classes |
|
|
35
|
+
| `onChange` | `function` | No | Change handler |
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// Email input
|
|
41
|
+
<Input name="email" type="email" placeholder="you@example.com" />
|
|
42
|
+
|
|
43
|
+
// Password input
|
|
44
|
+
<Input name="password" type="password" required />
|
|
45
|
+
|
|
46
|
+
// Disabled input
|
|
47
|
+
<Input name="field" value="Read only" disabled />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## See Also
|
|
51
|
+
|
|
52
|
+
- [Textarea](./Textarea.md)
|
|
53
|
+
- [FormField](../forms/FormField.md)
|
|
54
|
+
- [ContactForm](../forms/ContactForm.md)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# MobileLinks
|
|
2
|
+
|
|
3
|
+
Mobile-optimized link group component.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { MobileLinks } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<MobileLinks
|
|
17
|
+
links={[
|
|
18
|
+
{ label: 'Home', href: '/', icon: 'home' },
|
|
19
|
+
{ label: 'About', href: '/about', icon: 'info' },
|
|
20
|
+
{ label: 'Contact', href: '/contact', icon: 'mail' },
|
|
21
|
+
]}
|
|
22
|
+
/>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Required | Description |
|
|
28
|
+
|------|------|----------|-------------|
|
|
29
|
+
| `links` | `MobileLink[]` | Yes | Link items |
|
|
30
|
+
| `className` | `string` | No | Custom classes |
|
|
31
|
+
|
|
32
|
+
### MobileLink
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Required | Description |
|
|
35
|
+
|------|------|----------|-------------|
|
|
36
|
+
| `label` | `string \| LocalizedString` | Yes | Link label |
|
|
37
|
+
| `href` | `string` | Yes | Link URL |
|
|
38
|
+
| `icon` | `string` | No | Icon name |
|
|
39
|
+
|
|
40
|
+
## See Also
|
|
41
|
+
|
|
42
|
+
- [Header](../layout/Header.md)
|
|
43
|
+
- Mobile navigation helper component
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Modal
|
|
2
|
+
|
|
3
|
+
Accessible dialog/modal component.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Modal } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Client Component (`/client` export)
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Modal
|
|
17
|
+
isOpen={isOpen}
|
|
18
|
+
onClose={() => setIsOpen(false)}
|
|
19
|
+
title="Modal Title"
|
|
20
|
+
>
|
|
21
|
+
<p>Modal content goes here.</p>
|
|
22
|
+
</Modal>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Required | Description |
|
|
28
|
+
|------|------|----------|-------------|
|
|
29
|
+
| `isOpen` | `boolean` | Yes | Modal open state |
|
|
30
|
+
| `onClose` | `function` | Yes | Close handler |
|
|
31
|
+
| `title` | `string \| LocalizedString` | No | Modal title |
|
|
32
|
+
| `children` | `ReactNode` | Yes | Modal content |
|
|
33
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | No | Modal size |
|
|
34
|
+
| `className` | `string` | No | Custom classes |
|
|
35
|
+
|
|
36
|
+
## Examples
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// Basic modal
|
|
40
|
+
<Modal
|
|
41
|
+
isOpen={showModal}
|
|
42
|
+
onClose={() => setShowModal(false)}
|
|
43
|
+
title="Confirm Action"
|
|
44
|
+
>
|
|
45
|
+
<p>Are you sure you want to proceed?</p>
|
|
46
|
+
<div className="flex gap-4 mt-4">
|
|
47
|
+
<Button onClick={handleConfirm}>Confirm</Button>
|
|
48
|
+
<Button variant="outline" onClick={() => setShowModal(false)}>Cancel</Button>
|
|
49
|
+
</div>
|
|
50
|
+
</Modal>
|
|
51
|
+
|
|
52
|
+
// Large modal
|
|
53
|
+
<Modal isOpen={isOpen} onClose={onClose} size="lg" title="Details">
|
|
54
|
+
{/* content */}
|
|
55
|
+
</Modal>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## See Also
|
|
59
|
+
|
|
60
|
+
- [Button](./Button.md)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Tabs
|
|
2
|
+
|
|
3
|
+
Tabbed interface component.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Tabs } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Client Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Tabs
|
|
17
|
+
tabs={[
|
|
18
|
+
{ id: 'tab1', label: 'Tab 1', content: <div>Content 1</div> },
|
|
19
|
+
{ id: 'tab2', label: 'Tab 2', content: <div>Content 2</div> },
|
|
20
|
+
]}
|
|
21
|
+
/>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
| Prop | Type | Required | Description |
|
|
27
|
+
|------|------|----------|-------------|
|
|
28
|
+
| `tabs` | `TabItem[]` | Yes | Tab items |
|
|
29
|
+
| `defaultTab` | `string` | No | Default active tab ID |
|
|
30
|
+
| `className` | `string` | No | Custom classes |
|
|
31
|
+
|
|
32
|
+
### TabItem
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Required | Description |
|
|
35
|
+
|------|------|----------|-------------|
|
|
36
|
+
| `id` | `string` | Yes | Tab identifier |
|
|
37
|
+
| `label` | `string \| LocalizedString` | Yes | Tab label |
|
|
38
|
+
| `content` | `ReactNode` | Yes | Tab content |
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
<Tabs
|
|
44
|
+
tabs={[
|
|
45
|
+
{
|
|
46
|
+
id: 'features',
|
|
47
|
+
label: 'Features',
|
|
48
|
+
content: <div>Features content...</div>
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'pricing',
|
|
52
|
+
label: 'Pricing',
|
|
53
|
+
content: <div>Pricing content...</div>
|
|
54
|
+
},
|
|
55
|
+
]}
|
|
56
|
+
defaultTab="features"
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## See Also
|
|
61
|
+
|
|
62
|
+
- [Modal](./Modal.md)
|