@donotdev/cli 0.0.3 → 0.0.5
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/dependencies-matrix.json +194 -110
- package/dist/bin/commands/bump.d.ts +1 -1
- package/dist/bin/commands/bump.js +103 -96
- package/dist/bin/commands/create-app.js +40 -28
- package/dist/bin/commands/create-project.js +40 -28
- package/dist/bin/commands/format.d.ts +1 -1
- package/dist/bin/commands/lint.d.ts +1 -1
- package/dist/index.js +40 -28
- package/package.json +1 -9
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +5 -5
- package/templates/app-demo/src/themes.css.example +108 -156
- package/templates/app-next/src/app/ClientLayout.tsx.example +1 -1
- package/templates/app-next/src/locales/home_en.json.example +6 -0
- package/templates/app-next/src/pages/HomePage.tsx.example +152 -8
- package/templates/app-next/src/themes.css.example +92 -140
- package/templates/app-vite/src/App.tsx.example +3 -3
- package/templates/app-vite/src/locales/home_en.json.example +6 -0
- package/templates/app-vite/src/pages/HomePage.tsx.example +149 -8
- package/templates/app-vite/src/themes.css.example +90 -138
- package/templates/root-consumer/guides/AGENT_START_HERE.md.example +297 -53
- package/templates/root-consumer/guides/COMPONENTS_ADV.md.example +360 -0
- package/templates/root-consumer/guides/COMPONENTS_ATOMIC.md.example +134 -0
- package/templates/root-consumer/guides/COMPONENTS_CRUD.md.example +70 -0
- package/templates/root-consumer/guides/COMPONENTS_UI.md.example +141 -0
- package/templates/root-consumer/guides/ENV_SETUP.md.example +14 -0
- package/templates/root-consumer/guides/INDEX.md.example +17 -25
- package/templates/root-consumer/guides/SETUP_AUTH.md.example +77 -0
- package/templates/root-consumer/guides/SETUP_BILLING.md.example +78 -0
- package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +62 -0
- package/templates/root-consumer/guides/SETUP_I18N.md.example +187 -0
- package/templates/root-consumer/guides/SETUP_LAYOUTS.md.example +126 -0
- package/templates/root-consumer/guides/SETUP_OAUTH.md.example +53 -0
- package/templates/root-consumer/guides/SETUP_PAGES.md.example +120 -0
- package/templates/root-consumer/guides/SETUP_THEMES.md.example +107 -0
- package/templates/root-consumer/guides/advanced/COOKIE_REFERENCE.md.example +252 -0
- package/templates/root-consumer/guides/{EMULATOR_SETUP.md.example → advanced/EMULATORS.md.example} +1 -1
- package/templates/root-consumer/guides/{VERSION_CONTROL.md.example → advanced/VERSION_CONTROL.md.example} +0 -7
- package/templates/root-consumer/guides/AUTH_SETUP.md.example +0 -92
- package/templates/root-consumer/guides/BILLING_SETUP.md.example +0 -120
- package/templates/root-consumer/guides/CLI.md.example +0 -293
- package/templates/root-consumer/guides/COMPONENTS.md.example +0 -875
- package/templates/root-consumer/guides/FEATURES.md.example +0 -286
- package/templates/root-consumer/guides/FRAMEWORK_OVERVIEW.md.example +0 -97
- package/templates/root-consumer/guides/FUNCTIONS.md.example +0 -177
- package/templates/root-consumer/guides/GETTING_STARTED.md.example +0 -451
- package/templates/root-consumer/guides/HOW_TO_USE.md.example +0 -296
- package/templates/root-consumer/guides/I18N_SETUP.md.example +0 -204
- package/templates/root-consumer/guides/IMPORT_PATTERNS.md.example +0 -79
- package/templates/root-consumer/guides/INSTALLATION.md.example +0 -296
- package/templates/root-consumer/guides/LAYOUTS.md.example +0 -310
- package/templates/root-consumer/guides/PAGES_SETUP.md.example +0 -123
- package/templates/root-consumer/guides/STYLING.md.example +0 -273
- package/templates/root-consumer/guides/THEMING_SETUP.md.example +0 -119
- /package/templates/root-consumer/guides/{CONFIG_SETUP.md.example → SETUP_APP_CONFIG.md.example} +0 -0
- /package/templates/root-consumer/guides/{APP_CHECK_SETUP.md.example → advanced/APP_CHECK.md.example} +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Environment Setup
|
|
2
|
+
|
|
3
|
+
If you see this guide, you've already installed `@donotdev/cli` and ran `dndev init`.
|
|
4
|
+
|
|
5
|
+
## Next Steps
|
|
6
|
+
|
|
7
|
+
1. **AI Agent?** Have them read [AGENT_START_HERE.md](./AGENT_START_HERE.md)
|
|
8
|
+
2. **Create app:** `dndev create-app` - choose Vite (SPA) or Next.js (SSR), with optional backend
|
|
9
|
+
3. **Build:** Use auto-routing, auth, and translations
|
|
10
|
+
|
|
11
|
+
## Resources
|
|
12
|
+
|
|
13
|
+
- https://donotdev.com
|
|
14
|
+
- Discord: https://discord.gg/fbeYWDak
|
|
@@ -4,46 +4,38 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## Quick Setup
|
|
8
|
-
|
|
9
|
-
1. [INSTALLATION.md](./INSTALLATION.md) - Install framework packages
|
|
10
|
-
2. [GETTING_STARTED.md](./GETTING_STARTED.md) - Scaffold first app
|
|
11
|
-
3. [FRAMEWORK_OVERVIEW.md](./FRAMEWORK_OVERVIEW.md) - Package structure
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
7
|
## Core Setup
|
|
16
8
|
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
9
|
+
- [SETUP_PAGES.md](./SETUP_PAGES.md) - Pages & routing (pre-configured)
|
|
10
|
+
- [SETUP_APP_CONFIG.md](./SETUP_APP_CONFIG.md) - App + Vite configuration
|
|
11
|
+
- [SETUP_I18N.md](./SETUP_I18N.md) - Translations (pre-configured)
|
|
12
|
+
- [SETUP_THEMES.md](./SETUP_THEMES.md) - Themes & CSS variables (pre-configured)
|
|
13
|
+
- [SETUP_LAYOUTS.md](./SETUP_LAYOUTS.md) - Layout presets (pre-configured)
|
|
21
14
|
|
|
22
15
|
---
|
|
23
16
|
|
|
24
17
|
## Feature Setup
|
|
25
18
|
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
19
|
+
- [SETUP_AUTH.md](./SETUP_AUTH.md) - Authentication (pre-configured)
|
|
20
|
+
- [SETUP_OAUTH.md](./SETUP_OAUTH.md) - OAuth connections (pre-configured)
|
|
21
|
+
- [SETUP_BILLING.md](./SETUP_BILLING.md) - Stripe subscriptions (pre-configured)
|
|
22
|
+
- [SETUP_FUNCTIONS.md](./SETUP_FUNCTIONS.md) - Firebase Functions (pre-configured)
|
|
30
23
|
|
|
31
24
|
---
|
|
32
25
|
|
|
33
|
-
##
|
|
26
|
+
## Component Reference
|
|
34
27
|
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
- [
|
|
38
|
-
- [LAYOUTS.md](./LAYOUTS.md) - Layout presets
|
|
39
|
-
- [STYLING.md](./STYLING.md) - Styling system
|
|
40
|
-
- [IMPORT_PATTERNS.md](./IMPORT_PATTERNS.md) - Import conventions
|
|
28
|
+
- [COMPONENTS_ATOMIC.md](./COMPONENTS_ATOMIC.md) - Atomic components (@donotdev/components)
|
|
29
|
+
- [COMPONENTS_UI.md](./COMPONENTS_UI.md) - Layout/composition components (@donotdev/ui)
|
|
30
|
+
- [COMPONENTS_CRUD.md](./COMPONENTS_CRUD.md) - CRUD components (@donotdev/crud)
|
|
41
31
|
|
|
42
32
|
---
|
|
43
33
|
|
|
44
|
-
##
|
|
34
|
+
## Advanced
|
|
45
35
|
|
|
46
|
-
- [
|
|
36
|
+
- [advanced/APP_CHECK.md](./advanced/APP_CHECK.md) - Abuse protection
|
|
37
|
+
- [advanced/EMULATORS.md](./advanced/EMULATORS.md) - Local emulator setup
|
|
38
|
+
- [advanced/VERSION_CONTROL.md](./advanced/VERSION_CONTROL.md) - Package upgrades
|
|
47
39
|
|
|
48
40
|
---
|
|
49
41
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Setup: Authentication (Firebase Auth)
|
|
2
|
+
|
|
3
|
+
**Most is pre-configured.** Firebase Auth for user sign-in/sign-up. Add env vars and config. Framework handles providers, callbacks, sessions.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Standard Use
|
|
8
|
+
|
|
9
|
+
**Environment:**
|
|
10
|
+
```bash
|
|
11
|
+
# .env
|
|
12
|
+
VITE_AUTH_PARTNERS=password,emailLink,google,github,facebook
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Config:**
|
|
16
|
+
```typescript
|
|
17
|
+
// src/config/app.ts
|
|
18
|
+
export const appConfig: AppConfig = {
|
|
19
|
+
auth: {
|
|
20
|
+
authRoute: '/login',
|
|
21
|
+
loginPath: '/login', // Optional: undefined = header providers
|
|
22
|
+
profilePath: '/profile',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Firebase Console:** Enable providers in Authentication > Sign-in method
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Advanced: Protected Routes
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
// Basic protection
|
|
35
|
+
export const meta: PageMeta = {
|
|
36
|
+
namespace: NAMESPACE,
|
|
37
|
+
auth: { required: true },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Role-based access
|
|
41
|
+
export const meta: PageMeta = {
|
|
42
|
+
namespace: NAMESPACE,
|
|
43
|
+
auth: { required: true, role: 'admin' },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Tier-based access
|
|
47
|
+
export const meta: PageMeta = {
|
|
48
|
+
namespace: NAMESPACE,
|
|
49
|
+
auth: { required: true, tier: 'pro' },
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Advanced: Components & Hooks
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { useAuth } from '@donotdev/auth';
|
|
59
|
+
import { MultipleAuthProviders, AuthPartnerButton } from '@donotdev/auth';
|
|
60
|
+
import { AuthHeader, AuthMenu } from '@donotdev/ui';
|
|
61
|
+
import { LoginTemplate } from '@donotdev/templates';
|
|
62
|
+
|
|
63
|
+
// Hook
|
|
64
|
+
const user = useAuth('user');
|
|
65
|
+
const signIn = useAuth('signInWithEmail');
|
|
66
|
+
const signOut = useAuth('signOut');
|
|
67
|
+
|
|
68
|
+
// Components
|
|
69
|
+
<MultipleAuthProviders layout="vertical" emailMode="signin" />
|
|
70
|
+
<AuthPartnerButton partnerId="google" method="popup" />
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Pre-configured:** `AuthHeader` in layout (null if auth disabled), OAuth callbacks, session management, account linking.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
**Add env vars, get auth. Framework handles the rest.**
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Setup: Billing
|
|
2
|
+
|
|
3
|
+
**Most is pre-configured.** Create Stripe config files. Framework handles checkout, webhooks, subscriptions.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Standard Use
|
|
8
|
+
|
|
9
|
+
**Environment:**
|
|
10
|
+
```bash
|
|
11
|
+
# .env (frontend)
|
|
12
|
+
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
|
|
13
|
+
|
|
14
|
+
# functions/.env.local (local)
|
|
15
|
+
STRIPE_SECRET_KEY=sk_test_xxx
|
|
16
|
+
STRIPE_WEBHOOK_SECRET=whsec_xxx # From 'stripe listen'
|
|
17
|
+
|
|
18
|
+
# functions/.env (production)
|
|
19
|
+
STRIPE_SECRET_KEY=sk_live_xxx
|
|
20
|
+
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Stripe Dashboard:** Create products, copy Price IDs (`price_...`)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Advanced: Frontend Config
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// src/config/stripeFrontConfig.ts
|
|
31
|
+
export const stripeFrontConfig: StripeFrontConfig = {
|
|
32
|
+
pro_plan: {
|
|
33
|
+
name: 'Pro Plan',
|
|
34
|
+
price: 29,
|
|
35
|
+
currency: 'USD',
|
|
36
|
+
priceId: 'price_1234567890',
|
|
37
|
+
allowPromotionCodes: true,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Advanced: Backend Config
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// functions/src/config/stripeBackConfig.ts
|
|
48
|
+
export const stripeBackConfig: StripeBackConfig = {
|
|
49
|
+
pro_plan: {
|
|
50
|
+
type: 'StripeSubscription', // or 'StripePayment'
|
|
51
|
+
price: 2900, // In cents
|
|
52
|
+
priceId: process.env.STRIPE_PRICE_PRO_PLAN!,
|
|
53
|
+
tier: 'pro',
|
|
54
|
+
onPurchaseSuccess: async (userId, metadata) => { /* Grant features */ },
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// functions/src/index.ts
|
|
59
|
+
import { createCheckoutSession } from '@donotdev/functions/firebase';
|
|
60
|
+
export const createCheckout = createCheckoutSession(stripeBackConfig);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Advanced: Components & Hooks
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { useStripeBilling } from '@donotdev/billing';
|
|
69
|
+
import { SubscriptionTemplate, PaymentTemplate } from '@donotdev/templates';
|
|
70
|
+
import { ProductCard, SubscriptionManager } from '@donotdev/billing';
|
|
71
|
+
|
|
72
|
+
const checkout = useStripeBilling('checkout');
|
|
73
|
+
await checkout({ priceId: 'price_123', mode: 'subscription' });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
**Create config files, get billing. Framework handles the rest.**
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Setup: Firebase Functions
|
|
2
|
+
|
|
3
|
+
**Most is pre-configured.** Functions scaffolded. Just add config and deploy.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Standard Use
|
|
8
|
+
|
|
9
|
+
**Structure:**
|
|
10
|
+
```
|
|
11
|
+
functions/
|
|
12
|
+
├── src/
|
|
13
|
+
│ ├── billing/
|
|
14
|
+
│ └── index.ts
|
|
15
|
+
├── functions.yaml # Manually maintained
|
|
16
|
+
└── .env.local # Local secrets
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Environment:**
|
|
20
|
+
```bash
|
|
21
|
+
# .env.local (local)
|
|
22
|
+
STRIPE_SECRET_KEY=sk_test_...
|
|
23
|
+
|
|
24
|
+
# .env (production, synced via dndev sync-secrets)
|
|
25
|
+
STRIPE_SECRET_KEY=sk_live_...
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Advanced: Adding Functions
|
|
31
|
+
|
|
32
|
+
1. **Create:** `src/billing/myFunction.ts`
|
|
33
|
+
2. **Export:** `export * from './billing/myFunction.js';` in `src/index.ts`
|
|
34
|
+
3. **Add to functions.yaml:**
|
|
35
|
+
```yaml
|
|
36
|
+
endpoints:
|
|
37
|
+
myFunction:
|
|
38
|
+
region: [europe-west1]
|
|
39
|
+
platform: gcfv2
|
|
40
|
+
httpsTrigger: {}
|
|
41
|
+
entryPoint: myFunction
|
|
42
|
+
labels: {}
|
|
43
|
+
```
|
|
44
|
+
4. **Deploy:** `dndev deploy`
|
|
45
|
+
|
|
46
|
+
**Critical:** Every exported function must be in `functions.yaml` or it won't deploy.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Advanced: Framework Integration
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// Your function = framework + your config
|
|
54
|
+
import { createCheckoutSession as generic } from '@donotdev/functions/firebase';
|
|
55
|
+
import { stripeBackConfig } from '../config/stripeBackConfig';
|
|
56
|
+
|
|
57
|
+
export const createCheckoutSession = generic(stripeBackConfig);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
**Add functions, get backend. Framework handles the rest.**
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Setup: Internationalization
|
|
2
|
+
|
|
3
|
+
**Most is pre-configured.** Drop translation files. Framework auto-discovers languages.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Translation File Locations (CRITICAL)
|
|
8
|
+
|
|
9
|
+
**Two paths - choose based on when translations are needed:**
|
|
10
|
+
|
|
11
|
+
1. **Eager (`src/locales/`)**: Always loaded - use for common UI, navigation, app-wide content
|
|
12
|
+
2. **Lazy (`src/pages/locales/`)**: Loaded when page loads - use for page-specific content
|
|
13
|
+
|
|
14
|
+
**✅ RULE OF THUMB:**
|
|
15
|
+
- **Eager**: Navigation, buttons, common messages (used everywhere)
|
|
16
|
+
- **Lazy**: Page content, feature content, large text blocks (used on specific pages)
|
|
17
|
+
|
|
18
|
+
**Framework auto-discovers both paths. No configuration needed.**
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Standard Use
|
|
23
|
+
|
|
24
|
+
**CRITICAL: Two Translation Paths - Choose Based on When Translations Are Needed**
|
|
25
|
+
|
|
26
|
+
### Eager Translations (Always Loaded)
|
|
27
|
+
**Path:** `src/locales/<namespace>_<2-char-ISO>.json`
|
|
28
|
+
|
|
29
|
+
**Use for:**
|
|
30
|
+
- Common UI elements (buttons, labels, navigation)
|
|
31
|
+
- Critical app-wide translations (app name, common messages)
|
|
32
|
+
- Translations needed on every page
|
|
33
|
+
|
|
34
|
+
**Example:**
|
|
35
|
+
```
|
|
36
|
+
src/
|
|
37
|
+
locales/
|
|
38
|
+
common_en.json # ✅ Eager - always available
|
|
39
|
+
common_fr.json
|
|
40
|
+
navigation_en.json # ✅ Eager - used in header/sidebar
|
|
41
|
+
navigation_fr.json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Lazy Translations (Loaded When Page Loads)
|
|
45
|
+
**Path:** `src/pages/locales/<namespace>_<2-char-ISO>.json`
|
|
46
|
+
|
|
47
|
+
**Use for:**
|
|
48
|
+
- Page-specific content (page titles, descriptions, page content)
|
|
49
|
+
- Feature-specific translations (dashboard, blog, admin)
|
|
50
|
+
- Translations only needed when that page/feature is accessed
|
|
51
|
+
|
|
52
|
+
**Example:**
|
|
53
|
+
```
|
|
54
|
+
src/
|
|
55
|
+
pages/
|
|
56
|
+
HomePage.tsx
|
|
57
|
+
locales/
|
|
58
|
+
home_en.json # ✅ Lazy - loaded when HomePage loads
|
|
59
|
+
home_fr.json
|
|
60
|
+
dashboard/
|
|
61
|
+
DashboardPage.tsx
|
|
62
|
+
locales/
|
|
63
|
+
dashboard_en.json # ✅ Lazy - loaded when DashboardPage loads
|
|
64
|
+
dashboard_fr.json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**✅ DECISION GUIDE:**
|
|
68
|
+
- **Eager (`src/locales/`)**: Navigation, common buttons, app-wide messages
|
|
69
|
+
- **Lazy (`src/pages/locales/`)**: Page content, feature-specific content, large text blocks
|
|
70
|
+
|
|
71
|
+
**Usage:**
|
|
72
|
+
```tsx
|
|
73
|
+
import { useTranslation } from '@donotdev/core';
|
|
74
|
+
|
|
75
|
+
// Eager namespace (common, navigation, etc.)
|
|
76
|
+
const { t } = useTranslation('common');
|
|
77
|
+
t('app.title');
|
|
78
|
+
|
|
79
|
+
// Lazy namespace (page-specific)
|
|
80
|
+
const { t } = useTranslation('home');
|
|
81
|
+
t('hero.title');
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**LanguageSelector:** Included in layout presets. Import from `@donotdev/core` if needed elsewhere.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Advanced: Array Translations
|
|
89
|
+
|
|
90
|
+
### Low-level: translateArray
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { translateArray, translateObjectArray, maybeTranslate } from '@donotdev/core';
|
|
94
|
+
|
|
95
|
+
// Get array of strings (filters missing translations automatically)
|
|
96
|
+
const benefits = translateArray(t, 'benefits', 10); // Up to 10 items (benefits.0-9), safe if only 4 exist
|
|
97
|
+
const features = translateArray(t, 'features.list', 5); // Nested keys work
|
|
98
|
+
|
|
99
|
+
// Get array of objects
|
|
100
|
+
const cases = translateObjectArray(t, 'cases', 10, ['useCase', 'bestFit']);
|
|
101
|
+
|
|
102
|
+
// Auto-detect if value is a translation key or literal string
|
|
103
|
+
maybeTranslate(t, 'products.earlyBird.name');
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### High-level: tList (Recommended for Cards)
|
|
107
|
+
|
|
108
|
+
`tList` wraps `translateArray` and returns a `List` component ready for `Card` content:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { tList } from '@donotdev/ui';
|
|
112
|
+
|
|
113
|
+
// With default icon (CheckCircle)
|
|
114
|
+
<Card content={tList(t, 'features.items', 4)} />
|
|
115
|
+
|
|
116
|
+
// With custom icon
|
|
117
|
+
<Card content={tList(t, 'features.items', 4, Star)} />
|
|
118
|
+
|
|
119
|
+
// Without icon (for emoji-prefixed labels like "🚀 Kick-off")
|
|
120
|
+
<Card content={tList(t, 'features.items', 4, null)} />
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**JSON structure:**
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"features": {
|
|
127
|
+
"items": [
|
|
128
|
+
"Feature 1",
|
|
129
|
+
"Feature 2",
|
|
130
|
+
"Feature 3"
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Advanced: Rich Text (Trans)
|
|
139
|
+
|
|
140
|
+
For inline styling in translations, use `Trans` instead of `t()`. Use when translations contain HTML-like tags for styling.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { Trans } from '@donotdev/core';
|
|
144
|
+
|
|
145
|
+
// Translation: "<accent>MVP</accent> in 2 weeks"
|
|
146
|
+
<HeroSection title={<Trans ns={NAMESPACE} i18nKey="hero.title" />} />
|
|
147
|
+
|
|
148
|
+
// Translation: "I need <accent>Clarity</accent>"
|
|
149
|
+
<Card title={<Trans ns={NAMESPACE} i18nKey="products.transformation.title" />} />
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**JSON with tags:**
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"hero": {
|
|
156
|
+
"title": "Idea to <accent>MVP</accent> in 2 weeks"
|
|
157
|
+
},
|
|
158
|
+
"products": {
|
|
159
|
+
"transformation": {
|
|
160
|
+
"title": "I need <accent>Clarity</accent>",
|
|
161
|
+
"subtitle": "...for a <accent>critical</accent> application"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Supported tags:** `<accent>` `<primary>` `<muted>` `<success>` `<warning>` `<error>` `<bold>` `<code>`
|
|
168
|
+
|
|
169
|
+
**Note:** `Trans` accepts `ns` prop (string) for namespace. Use `t()` for plain strings, `Trans` for rich text with styling tags.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Advanced: I18N Components
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
import { LanguageSelector, LanguageFAB, FAQSection, TranslatedText, useLanguageSelector } from '@donotdev/core';
|
|
177
|
+
|
|
178
|
+
<LanguageSelector display="auto" /> // Already in presets
|
|
179
|
+
<LanguageFAB /> // Floating action button
|
|
180
|
+
<FAQSection items={faqItems} namespace="faq" />
|
|
181
|
+
<TranslatedText keyPath="welcome.message" namespace="home" />
|
|
182
|
+
const { languages, currentLanguage } = useLanguageSelector();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
**Drop files, get languages. Framework handles the rest.**
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Setup: Layouts
|
|
2
|
+
|
|
3
|
+
**Most is pre-configured.** Choose preset in `config/app.ts`. Framework handles header, sidebar, footer, auth, themes, languages.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Standard Use
|
|
8
|
+
|
|
9
|
+
**Choose preset:**
|
|
10
|
+
```typescript
|
|
11
|
+
// config/app.ts
|
|
12
|
+
export const appConfig: AppConfig = {
|
|
13
|
+
preset: 'landing', // landing | admin | moolti | docs | blog | game | plain
|
|
14
|
+
};
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**7 presets:** `landing` (marketing), `admin` (dashboards), `moolti` (SaaS), `docs` (documentation), `blog` (content), `game` (mobile), `plain` (minimal).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Preset Capabilities
|
|
22
|
+
|
|
23
|
+
**The `docs` preset AUTOMATICALLY generates sidebar navigation from your `src/pages` files. You do not need to configure a sidebar manually.**
|
|
24
|
+
|
|
25
|
+
All presets automatically include these components when applicable:
|
|
26
|
+
|
|
27
|
+
* **LanguageSelector** - Automatically shown if more than 1 language is configured
|
|
28
|
+
* **ThemeToggle** - Automatically shown if more than 1 theme is available
|
|
29
|
+
* **AuthMenu** - Automatically shown if auth is configured in `.env` (Firebase keys present)
|
|
30
|
+
* **Navigation Menu** - Automatically generated from `src/pages/*Page.tsx` files for sidebars
|
|
31
|
+
* **GoTo Component** - Command palette (Cmd+K) for quick navigation - always available
|
|
32
|
+
* **Footer** - Automatic footer with copyright and legal links
|
|
33
|
+
* **LegalLinks + Copyright** - Automatically included in footer from `config/legal.ts`
|
|
34
|
+
|
|
35
|
+
**You don't need to add these manually - the framework handles them based on your configuration.**
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Advanced: Slot Overrides
|
|
40
|
+
|
|
41
|
+
**Customize zones:**
|
|
42
|
+
```tsx
|
|
43
|
+
<ViteAppProviders
|
|
44
|
+
config={appConfig}
|
|
45
|
+
layout={{
|
|
46
|
+
header: {
|
|
47
|
+
start: () => <CustomLogo />, // Override start zone
|
|
48
|
+
center: () => <SearchBar />, // Override center zone
|
|
49
|
+
end: () => <UserMenu />, // Override end zone
|
|
50
|
+
},
|
|
51
|
+
sidebar: {
|
|
52
|
+
top: () => <Branding />, // Override top zone
|
|
53
|
+
content: () => <CustomNav />, // Override content zone
|
|
54
|
+
bottom: () => <UserProfile />, // Override bottom zone
|
|
55
|
+
},
|
|
56
|
+
footer: () => <CustomFooter />, // Replace entire footer
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Hide zones:**
|
|
62
|
+
```tsx
|
|
63
|
+
layout={{
|
|
64
|
+
header: {
|
|
65
|
+
center: () => null, // Hide center zone
|
|
66
|
+
},
|
|
67
|
+
footer: () => null, // Hide footer
|
|
68
|
+
}}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Available slots:** `header.start/center/end`, `sidebar.top/content/bottom`, `footer`, `mergedbar` (mobile nav).
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Advanced: CSS Variable Overrides
|
|
76
|
+
|
|
77
|
+
**Override dimensions in `src/themes.css`:**
|
|
78
|
+
```css
|
|
79
|
+
:root {
|
|
80
|
+
--header-height: 96px;
|
|
81
|
+
--sidebar-width: 320px;
|
|
82
|
+
--main-max-width: 1480px;
|
|
83
|
+
--footer-height: 64px;
|
|
84
|
+
--section-gap: 2rem;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Framework auto-computes:** Spacing, typography, responsive breakpoints.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Advanced: Density System
|
|
93
|
+
|
|
94
|
+
**Global density:**
|
|
95
|
+
```tsx
|
|
96
|
+
layout={{
|
|
97
|
+
density: 'compact', // compact | standard | expressive
|
|
98
|
+
}}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Per-page density:**
|
|
102
|
+
```tsx
|
|
103
|
+
<PageContainer density="expressive">
|
|
104
|
+
<HeroSection title="Hero" />
|
|
105
|
+
</PageContainer>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Three densities:** `compact` (1.2×), `standard` (1.25×), `expressive` (1.333×).
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Advanced: Runtime Preset Changes
|
|
113
|
+
|
|
114
|
+
**Change preset programmatically:**
|
|
115
|
+
```tsx
|
|
116
|
+
import { useLayout } from '@donotdev/core';
|
|
117
|
+
|
|
118
|
+
const setLayoutPreset = useLayout('setLayoutPreset');
|
|
119
|
+
setLayoutPreset('plain'); // Switch to plain layout
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Pre-configured:** All presets handle auth, themes, languages automatically.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
**Choose preset, get layout. Framework handles the rest.**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Setup: OAuth (Third-Party Connections)
|
|
2
|
+
|
|
3
|
+
**Most is pre-configured.** Connect to Spotify, LinkedIn, GitHub, etc. for API access. Add env vars. Framework handles OAuth flows, token exchange, refresh.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Standard Use
|
|
8
|
+
|
|
9
|
+
**Environment:**
|
|
10
|
+
```bash
|
|
11
|
+
# .env
|
|
12
|
+
VITE_OAUTH_PARTNERS=github,google,spotify,discord
|
|
13
|
+
VITE_OAUTH_GITHUB_CLIENT_ID=your_github_client_id
|
|
14
|
+
VITE_OAUTH_GOOGLE_CLIENT_ID=your_google_client_id
|
|
15
|
+
VITE_OAUTH_SPOTIFY_CLIENT_ID=your_spotify_client_id
|
|
16
|
+
VITE_OAUTH_DISCORD_CLIENT_ID=your_discord_client_id
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Available:** `github`, `google`, `spotify`, `discord`, `twitch`, `reddit`, `linkedin`, `slack`, `notion`, `medium`, `twitter`, `mastodon`, `youtube`
|
|
20
|
+
|
|
21
|
+
**OAuth Provider Dashboard:** Create OAuth apps, copy Client IDs, configure redirect URIs.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Advanced: Components & Hooks
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { useOAuth } from '@donotdev/oauth';
|
|
29
|
+
import { MultipleOAuthProviders, OAuthPartnerButton } from '@donotdev/oauth';
|
|
30
|
+
import { OAuthConnectionModal } from '@donotdev/oauth';
|
|
31
|
+
|
|
32
|
+
// Hook
|
|
33
|
+
const connect = useOAuth('connect');
|
|
34
|
+
const disconnect = useOAuth('disconnect');
|
|
35
|
+
const isConnected = useOAuth('isConnected');
|
|
36
|
+
const loading = useOAuth('loading');
|
|
37
|
+
const error = useOAuth('error');
|
|
38
|
+
|
|
39
|
+
await connect('github', 'api-access'); // Purpose: 'authentication' | 'api-access'
|
|
40
|
+
await disconnect('github');
|
|
41
|
+
const connected = isConnected('github');
|
|
42
|
+
|
|
43
|
+
// Components
|
|
44
|
+
<MultipleOAuthProviders purpose="api-access" layout="vertical" />
|
|
45
|
+
<OAuthPartnerButton partnerId="github" purpose="api-access" />
|
|
46
|
+
<OAuthConnectionModal />
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Pre-configured:** Auto-discovers enabled providers, handles PKCE flow, token refresh, callbacks.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
**Add env vars, get OAuth. Framework handles the rest.**
|