@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,191 @@
|
|
|
1
|
+
# RTL (Right-to-Left) Support
|
|
2
|
+
|
|
3
|
+
Support for right-to-left languages like Arabic and Hebrew.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
Specify RTL locales in configuration:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export const i18nConfig = {
|
|
11
|
+
locales: ['en', 'ar', 'he', 'fr'],
|
|
12
|
+
defaultLocale: 'en',
|
|
13
|
+
rtlLocales: ['ar', 'he'], // RTL languages
|
|
14
|
+
};
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## HTML Direction Attribute
|
|
18
|
+
|
|
19
|
+
Set the `dir` attribute on the root HTML element:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// app/[locale]/layout.tsx
|
|
23
|
+
import { getTextDirection } from '@zoyth/simple-site-framework/lib/i18n';
|
|
24
|
+
|
|
25
|
+
export default function RootLayout({ children, params }) {
|
|
26
|
+
const { locale } = params;
|
|
27
|
+
const direction = getTextDirection(locale);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<html lang={locale} dir={direction}>
|
|
31
|
+
<body>{children}</body>
|
|
32
|
+
</html>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This outputs:
|
|
38
|
+
- `<html dir="ltr">` for LTR languages (English, French, etc.)
|
|
39
|
+
- `<html dir="rtl">` for RTL languages (Arabic, Hebrew)
|
|
40
|
+
|
|
41
|
+
## Utility Functions
|
|
42
|
+
|
|
43
|
+
### isRtlLocale
|
|
44
|
+
|
|
45
|
+
Check if a locale is RTL:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { isRtlLocale } from '@zoyth/simple-site-framework/lib/i18n';
|
|
49
|
+
|
|
50
|
+
isRtlLocale('ar'); // true
|
|
51
|
+
isRtlLocale('he'); // true
|
|
52
|
+
isRtlLocale('en'); // false
|
|
53
|
+
isRtlLocale('fr'); // false
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### getTextDirection
|
|
57
|
+
|
|
58
|
+
Get text direction for locale:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { getTextDirection } from '@zoyth/simple-site-framework/lib/i18n';
|
|
62
|
+
|
|
63
|
+
getTextDirection('ar'); // 'rtl'
|
|
64
|
+
getTextDirection('en'); // 'ltr'
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## CSS Considerations
|
|
68
|
+
|
|
69
|
+
### Logical Properties
|
|
70
|
+
|
|
71
|
+
Use CSS logical properties for RTL compatibility:
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
/* ✅ Good - RTL compatible */
|
|
75
|
+
.element {
|
|
76
|
+
margin-inline-start: 1rem;
|
|
77
|
+
padding-inline-end: 2rem;
|
|
78
|
+
border-inline-start: 1px solid;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ❌ Bad - Not RTL compatible */
|
|
82
|
+
.element {
|
|
83
|
+
margin-left: 1rem;
|
|
84
|
+
padding-right: 2rem;
|
|
85
|
+
border-left: 1px solid;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Tailwind CSS
|
|
90
|
+
|
|
91
|
+
Tailwind v3+ supports RTL with logical properties:
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
<div className="ms-4 pe-6">
|
|
95
|
+
{/* margin-inline-start: 1rem, padding-inline-end: 1.5rem */}
|
|
96
|
+
</div>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Or use RTL variants:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<div className="ml-4 rtl:mr-4 rtl:ml-0">
|
|
103
|
+
{/* Margin left in LTR, margin right in RTL */}
|
|
104
|
+
</div>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Component Adjustments
|
|
108
|
+
|
|
109
|
+
### Icons and Arrows
|
|
110
|
+
|
|
111
|
+
Flip directional icons in RTL:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { isRtlLocale } from '@zoyth/simple-site-framework/lib/i18n';
|
|
115
|
+
|
|
116
|
+
function NavigationArrow({ locale }: Props) {
|
|
117
|
+
const isRtl = isRtlLocale(locale);
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<svg className={isRtl ? 'scale-x-[-1]' : ''}>
|
|
121
|
+
{/* Arrow icon */}
|
|
122
|
+
</svg>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Text Alignment
|
|
128
|
+
|
|
129
|
+
Adjust text alignment based on direction:
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<p className="text-start">
|
|
133
|
+
{/* Aligns left in LTR, right in RTL */}
|
|
134
|
+
</p>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Testing RTL
|
|
138
|
+
|
|
139
|
+
### Browser Testing
|
|
140
|
+
|
|
141
|
+
1. Add Arabic or Hebrew to your config
|
|
142
|
+
2. Switch to RTL locale via LanguageSelector
|
|
143
|
+
3. Verify layout mirrors correctly
|
|
144
|
+
4. Check navigation, forms, and interactive elements
|
|
145
|
+
|
|
146
|
+
### Development Tools
|
|
147
|
+
|
|
148
|
+
Chrome DevTools can force RTL:
|
|
149
|
+
1. Open DevTools
|
|
150
|
+
2. Rendering tab → Enable "Emulate RTL"
|
|
151
|
+
|
|
152
|
+
## Common RTL Issues
|
|
153
|
+
|
|
154
|
+
### Floats and Positioning
|
|
155
|
+
|
|
156
|
+
Use flexbox/grid instead of floats:
|
|
157
|
+
|
|
158
|
+
```css
|
|
159
|
+
/* ✅ Good */
|
|
160
|
+
.container {
|
|
161
|
+
display: flex;
|
|
162
|
+
justify-content: flex-start;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* ❌ Avoid */
|
|
166
|
+
.container {
|
|
167
|
+
float: left;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Absolute Positioning
|
|
172
|
+
|
|
173
|
+
Use logical properties:
|
|
174
|
+
|
|
175
|
+
```css
|
|
176
|
+
/* ✅ Good */
|
|
177
|
+
.element {
|
|
178
|
+
inset-inline-start: 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* ❌ Avoid */
|
|
182
|
+
.element {
|
|
183
|
+
left: 0;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## See Also
|
|
188
|
+
|
|
189
|
+
- [Configuration](./configuration.md)
|
|
190
|
+
- [CSS Logical Properties (MDN)](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties)
|
|
191
|
+
- [Tailwind RTL Support](https://tailwindcss.com/docs/hover-focus-and-other-states#rtl-support)
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Managing Translations
|
|
2
|
+
|
|
3
|
+
Organize and manage translated content across multiple languages.
|
|
4
|
+
|
|
5
|
+
## LocalizedString Type
|
|
6
|
+
|
|
7
|
+
The core type for translated content:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
type LocalizedString = {
|
|
11
|
+
[locale: string]: string;
|
|
12
|
+
};
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage in Components
|
|
16
|
+
|
|
17
|
+
All framework components accept LocalizedString:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
const content = {
|
|
21
|
+
heading: {
|
|
22
|
+
en: 'Welcome to Our Site',
|
|
23
|
+
fr: 'Bienvenue sur notre site',
|
|
24
|
+
es: 'Bienvenido a nuestro sitio',
|
|
25
|
+
},
|
|
26
|
+
description: {
|
|
27
|
+
en: 'Professional services for your business',
|
|
28
|
+
fr: 'Services professionnels pour votre entreprise',
|
|
29
|
+
es: 'Servicios profesionales para su negocio',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
<HeroSection
|
|
34
|
+
heading={content.heading}
|
|
35
|
+
description={content.description}
|
|
36
|
+
locale={locale}
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Translation Organization
|
|
41
|
+
|
|
42
|
+
### Option 1: Configuration Files
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// config/translations/en.ts
|
|
46
|
+
export const en = {
|
|
47
|
+
nav: {
|
|
48
|
+
home: 'Home',
|
|
49
|
+
about: 'About',
|
|
50
|
+
services: 'Services',
|
|
51
|
+
contact: 'Contact',
|
|
52
|
+
},
|
|
53
|
+
hero: {
|
|
54
|
+
title: 'Welcome',
|
|
55
|
+
subtitle: 'Professional services',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// config/translations/fr.ts
|
|
60
|
+
export const fr = {
|
|
61
|
+
nav: {
|
|
62
|
+
home: 'Accueil',
|
|
63
|
+
about: 'À propos',
|
|
64
|
+
services: 'Services',
|
|
65
|
+
contact: 'Contact',
|
|
66
|
+
},
|
|
67
|
+
hero: {
|
|
68
|
+
title: 'Bienvenue',
|
|
69
|
+
subtitle: 'Services professionnels',
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Option 2: Inline LocalizedStrings
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const translations = {
|
|
78
|
+
title: { en: 'Welcome', fr: 'Bienvenue', es: 'Bienvenido' },
|
|
79
|
+
button: { en: 'Get Started', fr: 'Commencer', es: 'Comenzar' },
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Option 3: JSON Translation Files
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
// locales/en.json
|
|
87
|
+
{
|
|
88
|
+
"home": {
|
|
89
|
+
"hero": {
|
|
90
|
+
"title": "Welcome",
|
|
91
|
+
"subtitle": "Professional services"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Helper Utilities
|
|
98
|
+
|
|
99
|
+
### getLocalizedString
|
|
100
|
+
|
|
101
|
+
Extract string for specific locale:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { getLocalizedString } from '@zoyth/simple-site-framework/lib/i18n';
|
|
105
|
+
|
|
106
|
+
const heading = { en: 'Welcome', fr: 'Bienvenue' };
|
|
107
|
+
const text = getLocalizedString(heading, 'fr'); // 'Bienvenue'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Fallback Behavior
|
|
111
|
+
|
|
112
|
+
1. Requested locale
|
|
113
|
+
2. Default locale
|
|
114
|
+
3. First available translation
|
|
115
|
+
4. Empty string
|
|
116
|
+
|
|
117
|
+
## Best Practices
|
|
118
|
+
|
|
119
|
+
- Keep translations co-located with components when possible
|
|
120
|
+
- Use TypeScript to ensure translation completeness
|
|
121
|
+
- Provide default locale translation for all strings
|
|
122
|
+
- Consider using a translation management service for large projects
|
|
123
|
+
- Validate translations at build time
|
|
124
|
+
|
|
125
|
+
## See Also
|
|
126
|
+
|
|
127
|
+
- [Configuration](./configuration.md)
|
|
128
|
+
- [LocalizedString Type](../../api-reference/types.md)
|
|
129
|
+
- [Translation Examples](../../i18n/EXAMPLES.md)
|