@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,54 @@
|
|
|
1
|
+
# WhyChooseUsSection
|
|
2
|
+
|
|
3
|
+
"Why Choose Us" benefits section.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { WhyChooseUsSection } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<WhyChooseUsSection
|
|
17
|
+
heading="Why Choose Us"
|
|
18
|
+
reasons={[
|
|
19
|
+
{
|
|
20
|
+
title: 'Expert Team',
|
|
21
|
+
description: '15+ years of combined experience',
|
|
22
|
+
icon: 'users',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: 'Proven Results',
|
|
26
|
+
description: 'Over 200 successful projects',
|
|
27
|
+
icon: 'chart',
|
|
28
|
+
},
|
|
29
|
+
]}
|
|
30
|
+
/>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
| Prop | Type | Required | Description |
|
|
36
|
+
|------|------|----------|-------------|
|
|
37
|
+
| `heading` | `string \| LocalizedString` | Yes | Section heading |
|
|
38
|
+
| `description` | `string \| LocalizedString` | No | Section description |
|
|
39
|
+
| `reasons` | `Reason[]` | Yes | Reason items |
|
|
40
|
+
| `className` | `string` | No | Custom classes |
|
|
41
|
+
| `locale` | `string` | No | Current locale |
|
|
42
|
+
|
|
43
|
+
### Reason
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Required | Description |
|
|
46
|
+
|------|------|----------|-------------|
|
|
47
|
+
| `title` | `string \| LocalizedString` | Yes | Reason title |
|
|
48
|
+
| `description` | `string \| LocalizedString` | Yes | Reason description |
|
|
49
|
+
| `icon` | `string` | No | Icon name |
|
|
50
|
+
|
|
51
|
+
## See Also
|
|
52
|
+
|
|
53
|
+
- [FeaturesGrid](../FeaturesGrid.md)
|
|
54
|
+
- [AboutSection](./AboutSection.md)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
Navigation breadcrumb trail showing page hierarchy.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Breadcrumb } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Breadcrumb
|
|
17
|
+
items={[
|
|
18
|
+
{ label: 'Home', href: '/' },
|
|
19
|
+
{ label: 'Products', href: '/products' },
|
|
20
|
+
{ label: 'Widget' }
|
|
21
|
+
]}
|
|
22
|
+
/>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Required | Description |
|
|
28
|
+
|------|------|----------|-------------|
|
|
29
|
+
| `items` | `BreadcrumbItem[]` | Yes | Breadcrumb items |
|
|
30
|
+
| `separator` | `string` | No | Custom separator (default: '/') |
|
|
31
|
+
| `className` | `string` | No | Custom classes |
|
|
32
|
+
|
|
33
|
+
### BreadcrumbItem
|
|
34
|
+
|
|
35
|
+
| Prop | Type | Required | Description |
|
|
36
|
+
|------|------|----------|-------------|
|
|
37
|
+
| `label` | `string \| LocalizedString` | Yes | Item label |
|
|
38
|
+
| `href` | `string` | No | Link URL (omit for current page) |
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// Simple breadcrumb
|
|
44
|
+
<Breadcrumb
|
|
45
|
+
items={[
|
|
46
|
+
{ label: 'Home', href: '/' },
|
|
47
|
+
{ label: 'Blog', href: '/blog' },
|
|
48
|
+
{ label: 'Article Title' }
|
|
49
|
+
]}
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
// Custom separator
|
|
53
|
+
<Breadcrumb
|
|
54
|
+
items={items}
|
|
55
|
+
separator="›"
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
// Multi-language
|
|
59
|
+
<Breadcrumb
|
|
60
|
+
items={[
|
|
61
|
+
{ label: { en: 'Home', fr: 'Accueil' }, href: '/' },
|
|
62
|
+
{ label: { en: 'About', fr: 'À propos' } }
|
|
63
|
+
]}
|
|
64
|
+
locale={locale}
|
|
65
|
+
/>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## See Also
|
|
69
|
+
|
|
70
|
+
- [Header](../layout/Header.md)
|
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
Themeable button component with multiple variants and sizes. The fundamental interactive element used throughout the framework.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Button } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component (default export)
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Button>Click Me</Button>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Props
|
|
20
|
+
|
|
21
|
+
### Optional Props
|
|
22
|
+
|
|
23
|
+
| Prop | Type | Default | Description |
|
|
24
|
+
|------|------|---------|-------------|
|
|
25
|
+
| `variant` | `'filled' \| 'outline' \| 'ghost' \| 'link'` | `'filled'` | Button style variant |
|
|
26
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
|
|
27
|
+
| `disabled` | `boolean` | `false` | Disable button |
|
|
28
|
+
| `loading` | `boolean` | `false` | Show loading state |
|
|
29
|
+
| `className` | `string` | - | Custom CSS classes |
|
|
30
|
+
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML button type |
|
|
31
|
+
| `onClick` | `() => void` | - | Click handler |
|
|
32
|
+
| `children` | `ReactNode` | - | Button content |
|
|
33
|
+
|
|
34
|
+
## Variants
|
|
35
|
+
|
|
36
|
+
### Filled (Default)
|
|
37
|
+
|
|
38
|
+
Solid background, primary brand color:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
<Button variant="filled">
|
|
42
|
+
Get Started
|
|
43
|
+
</Button>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Use for:** Primary actions, main CTAs, submission buttons
|
|
47
|
+
|
|
48
|
+
### Outline
|
|
49
|
+
|
|
50
|
+
Transparent background with border:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
<Button variant="outline">
|
|
54
|
+
Learn More
|
|
55
|
+
</Button>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Use for:** Secondary actions, cancel buttons, alternative options
|
|
59
|
+
|
|
60
|
+
### Ghost
|
|
61
|
+
|
|
62
|
+
Transparent background, no border:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
<Button variant="ghost">
|
|
66
|
+
Skip
|
|
67
|
+
</Button>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Use for:** Tertiary actions, dismiss buttons, subtle interactions
|
|
71
|
+
|
|
72
|
+
### Link
|
|
73
|
+
|
|
74
|
+
Styled as a text link:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
<Button variant="link">
|
|
78
|
+
View Details
|
|
79
|
+
</Button>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Use for:** Inline actions, navigation, less prominent options
|
|
83
|
+
|
|
84
|
+
## Sizes
|
|
85
|
+
|
|
86
|
+
### Small
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
<Button size="sm">
|
|
90
|
+
Small Button
|
|
91
|
+
</Button>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Compact size for tight spaces, inline use.
|
|
95
|
+
|
|
96
|
+
### Medium (Default)
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
<Button size="md">
|
|
100
|
+
Medium Button
|
|
101
|
+
</Button>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Standard size for most use cases.
|
|
105
|
+
|
|
106
|
+
### Large
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
<Button size="lg">
|
|
110
|
+
Large Button
|
|
111
|
+
</Button>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Prominent size for hero CTAs, important actions.
|
|
115
|
+
|
|
116
|
+
## Examples
|
|
117
|
+
|
|
118
|
+
### Primary Action
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
<Button variant="filled" size="lg">
|
|
122
|
+
Start Free Trial
|
|
123
|
+
</Button>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Secondary Action
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
<Button variant="outline">
|
|
130
|
+
View Pricing
|
|
131
|
+
</Button>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Disabled State
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
<Button disabled>
|
|
138
|
+
Unavailable
|
|
139
|
+
</Button>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Loading State
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
<Button loading>
|
|
146
|
+
Processing...
|
|
147
|
+
</Button>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### With Click Handler
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
<Button
|
|
154
|
+
onClick={() => {
|
|
155
|
+
console.log('Button clicked!');
|
|
156
|
+
trackEvent('button_click');
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
Track This Click
|
|
160
|
+
</Button>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Form Submit
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
<form onSubmit={handleSubmit}>
|
|
167
|
+
<Button type="submit" variant="filled">
|
|
168
|
+
Submit Form
|
|
169
|
+
</Button>
|
|
170
|
+
</form>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Button Group
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
<div className="flex gap-4">
|
|
177
|
+
<Button variant="filled">
|
|
178
|
+
Save
|
|
179
|
+
</Button>
|
|
180
|
+
<Button variant="outline">
|
|
181
|
+
Cancel
|
|
182
|
+
</Button>
|
|
183
|
+
</div>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Full Width
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
<Button className="w-full">
|
|
190
|
+
Continue
|
|
191
|
+
</Button>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### With Icon
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
<Button>
|
|
198
|
+
<svg className="w-5 h-5 mr-2" /* ... */>
|
|
199
|
+
{/* icon */}
|
|
200
|
+
</svg>
|
|
201
|
+
Download PDF
|
|
202
|
+
</Button>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Custom Colors
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
<Button className="bg-purple-600 hover:bg-purple-700">
|
|
209
|
+
Custom Color
|
|
210
|
+
</Button>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Responsive Sizing
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
<Button className="text-sm md:text-base lg:text-lg">
|
|
217
|
+
Responsive Size
|
|
218
|
+
</Button>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Styling
|
|
222
|
+
|
|
223
|
+
### Theme Integration
|
|
224
|
+
|
|
225
|
+
Buttons automatically use your theme colors:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// In tailwind.config.ts
|
|
229
|
+
colors: {
|
|
230
|
+
primary: '#F16531',
|
|
231
|
+
'primary-hover': '#D9551C',
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Button uses these automatically
|
|
235
|
+
<Button variant="filled" /> // Uses primary and primary-hover
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Custom Styling
|
|
239
|
+
|
|
240
|
+
Override with className:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
<Button className="bg-gradient-to-r from-blue-500 to-purple-600">
|
|
244
|
+
Gradient Button
|
|
245
|
+
</Button>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Dark Mode Support
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
<Button className="dark:bg-gray-800 dark:text-white">
|
|
252
|
+
Dark Mode Button
|
|
253
|
+
</Button>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Accessibility
|
|
257
|
+
|
|
258
|
+
Button includes:
|
|
259
|
+
|
|
260
|
+
- ✅ Semantic `<button>` element
|
|
261
|
+
- ✅ Keyboard accessible (Enter/Space)
|
|
262
|
+
- ✅ Focus visible states
|
|
263
|
+
- ✅ Proper disabled state (not clickable)
|
|
264
|
+
- ✅ Loading state with aria-busy
|
|
265
|
+
- ✅ Sufficient color contrast (WCAG AA)
|
|
266
|
+
|
|
267
|
+
### ARIA Attributes
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
<Button
|
|
271
|
+
aria-label="Submit contact form"
|
|
272
|
+
aria-describedby="submit-help-text"
|
|
273
|
+
>
|
|
274
|
+
Submit
|
|
275
|
+
</Button>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Loading State Accessibility
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
<Button loading aria-busy="true">
|
|
282
|
+
Saving...
|
|
283
|
+
</Button>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Common Patterns
|
|
287
|
+
|
|
288
|
+
### Confirm/Cancel Pair
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
<div className="flex gap-4">
|
|
292
|
+
<Button
|
|
293
|
+
variant="filled"
|
|
294
|
+
onClick={handleConfirm}
|
|
295
|
+
>
|
|
296
|
+
Confirm
|
|
297
|
+
</Button>
|
|
298
|
+
<Button
|
|
299
|
+
variant="outline"
|
|
300
|
+
onClick={handleCancel}
|
|
301
|
+
>
|
|
302
|
+
Cancel
|
|
303
|
+
</Button>
|
|
304
|
+
</div>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### CTA with Secondary
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
<div className="flex flex-col sm:flex-row gap-4">
|
|
311
|
+
<Button variant="filled" size="lg">
|
|
312
|
+
Get Started Free
|
|
313
|
+
</Button>
|
|
314
|
+
<Button variant="outline" size="lg">
|
|
315
|
+
Schedule Demo
|
|
316
|
+
</Button>
|
|
317
|
+
</div>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Loading Button
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
function SubmitButton() {
|
|
324
|
+
const [loading, setLoading] = useState(false);
|
|
325
|
+
|
|
326
|
+
const handleClick = async () => {
|
|
327
|
+
setLoading(true);
|
|
328
|
+
await submitForm();
|
|
329
|
+
setLoading(false);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
return (
|
|
333
|
+
<Button loading={loading} onClick={handleClick}>
|
|
334
|
+
{loading ? 'Submitting...' : 'Submit'}
|
|
335
|
+
</Button>
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Conditional Disabled
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
<Button disabled={!isValid}>
|
|
344
|
+
Continue
|
|
345
|
+
</Button>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### With Analytics
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
<Button
|
|
352
|
+
onClick={() => {
|
|
353
|
+
trackEvent('cta_click', {
|
|
354
|
+
button_text: 'Start Trial',
|
|
355
|
+
location: 'hero'
|
|
356
|
+
});
|
|
357
|
+
router.push('/signup');
|
|
358
|
+
}}
|
|
359
|
+
>
|
|
360
|
+
Start Trial
|
|
361
|
+
</Button>
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Button as Link
|
|
365
|
+
|
|
366
|
+
For navigation, use Next.js Link:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import Link from 'next/link';
|
|
370
|
+
import { Button } from '@zoyth/simple-site-framework';
|
|
371
|
+
|
|
372
|
+
<Link href="/pricing">
|
|
373
|
+
<Button variant="outline">
|
|
374
|
+
View Pricing
|
|
375
|
+
</Button>
|
|
376
|
+
</Link>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Or use `<a>` styled as button:
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
<a
|
|
383
|
+
href="/pricing"
|
|
384
|
+
className="inline-flex items-center justify-center px-6 py-3 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors"
|
|
385
|
+
>
|
|
386
|
+
View Pricing
|
|
387
|
+
</a>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Form Integration
|
|
391
|
+
|
|
392
|
+
### Submit Button
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
<form onSubmit={handleSubmit}>
|
|
396
|
+
<input type="email" name="email" />
|
|
397
|
+
<Button type="submit" variant="filled">
|
|
398
|
+
Subscribe
|
|
399
|
+
</Button>
|
|
400
|
+
</form>
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Reset Button
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
<form>
|
|
407
|
+
{/* form fields */}
|
|
408
|
+
<div className="flex gap-4">
|
|
409
|
+
<Button type="submit" variant="filled">
|
|
410
|
+
Submit
|
|
411
|
+
</Button>
|
|
412
|
+
<Button type="reset" variant="ghost">
|
|
413
|
+
Reset
|
|
414
|
+
</Button>
|
|
415
|
+
</div>
|
|
416
|
+
</form>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Validation State
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
function FormWithValidation() {
|
|
423
|
+
const [isValid, setIsValid] = useState(false);
|
|
424
|
+
|
|
425
|
+
return (
|
|
426
|
+
<form>
|
|
427
|
+
<input onChange={e => setIsValid(e.target.value.length > 0)} />
|
|
428
|
+
<Button type="submit" disabled={!isValid}>
|
|
429
|
+
{isValid ? 'Submit' : 'Please fill in all fields'}
|
|
430
|
+
</Button>
|
|
431
|
+
</form>
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## Best Practices
|
|
437
|
+
|
|
438
|
+
### ✅ Do
|
|
439
|
+
|
|
440
|
+
- Use filled variant for primary actions
|
|
441
|
+
- Provide clear, action-oriented text
|
|
442
|
+
- Show loading state during async operations
|
|
443
|
+
- Disable buttons during submission
|
|
444
|
+
- Use appropriate size for context
|
|
445
|
+
- Include sufficient padding for touch targets (44px minimum)
|
|
446
|
+
- Test keyboard navigation
|
|
447
|
+
|
|
448
|
+
### ❌ Don't
|
|
449
|
+
|
|
450
|
+
- Use multiple filled buttons competing for attention
|
|
451
|
+
- Make buttons too small (hard to click)
|
|
452
|
+
- Use vague text like "Click Here" or "Submit"
|
|
453
|
+
- Forget to handle loading/disabled states
|
|
454
|
+
- Override focus styles without providing alternatives
|
|
455
|
+
- Make all buttons the same style (no hierarchy)
|
|
456
|
+
|
|
457
|
+
## Troubleshooting
|
|
458
|
+
|
|
459
|
+
### Button not styled
|
|
460
|
+
|
|
461
|
+
**Check:**
|
|
462
|
+
1. Tailwind config includes framework in `content` array
|
|
463
|
+
2. Theme colors are defined
|
|
464
|
+
3. Import is correct
|
|
465
|
+
4. No CSS overriding styles
|
|
466
|
+
|
|
467
|
+
### onClick not firing
|
|
468
|
+
|
|
469
|
+
**Check:**
|
|
470
|
+
1. Button is not disabled
|
|
471
|
+
2. No overlay blocking clicks
|
|
472
|
+
3. Event handler is properly bound
|
|
473
|
+
4. Not prevented by parent element
|
|
474
|
+
|
|
475
|
+
### Focus not visible
|
|
476
|
+
|
|
477
|
+
**Check:**
|
|
478
|
+
1. Focus styles not removed by CSS reset
|
|
479
|
+
2. Browser default focus styles working
|
|
480
|
+
3. Custom focus styles have sufficient contrast
|
|
481
|
+
|
|
482
|
+
### Loading spinner not showing
|
|
483
|
+
|
|
484
|
+
**Check:**
|
|
485
|
+
1. `loading` prop is `true`
|
|
486
|
+
2. Loading indicator is implemented in component
|
|
487
|
+
3. No CSS hiding the indicator
|
|
488
|
+
|
|
489
|
+
## Variants Reference
|
|
490
|
+
|
|
491
|
+
| Variant | Background | Border | Text Color | Use Case |
|
|
492
|
+
|---------|------------|--------|------------|----------|
|
|
493
|
+
| `filled` | Primary | None | White | Primary actions, main CTAs |
|
|
494
|
+
| `outline` | Transparent | Primary | Primary | Secondary actions, alternatives |
|
|
495
|
+
| `ghost` | Transparent | None | Primary | Tertiary actions, subtle |
|
|
496
|
+
| `link` | Transparent | None | Primary | Inline actions, navigation |
|
|
497
|
+
|
|
498
|
+
## Size Reference
|
|
499
|
+
|
|
500
|
+
| Size | Padding | Font Size | Use Case |
|
|
501
|
+
|------|---------|-----------|----------|
|
|
502
|
+
| `sm` | px-4 py-2 | text-sm | Compact spaces, inline use |
|
|
503
|
+
| `md` | px-6 py-3 | text-base | Standard buttons, forms |
|
|
504
|
+
| `lg` | px-8 py-4 | text-lg | Hero CTAs, prominent actions |
|
|
505
|
+
|
|
506
|
+
## Related Components
|
|
507
|
+
|
|
508
|
+
- **[CTASection](../sections/CTASection.md)** - Uses Button internally
|
|
509
|
+
- **[ContactForm](../forms/ContactForm.md)** - Form with submit button
|
|
510
|
+
- **[FormField](../forms/FormField.md)** - Form field with button
|
|
511
|
+
|
|
512
|
+
## API Reference
|
|
513
|
+
|
|
514
|
+
Full TypeScript definitions: **[API Reference](../../api/components.md#button)**
|