mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-22 09:26:41 +02:00
refactor: restructure
monorepo with apps/ and services/ directories
This commit is contained in:
parent
25824ed0ac
commit
ff80aeec1f
4062 changed files with 2592 additions and 1278 deletions
|
|
@ -1,742 +0,0 @@
|
|||
# UI Unification Strategy - Picture Monorepo
|
||||
|
||||
**Date:** 2025-10-08
|
||||
**Status:** Proposal
|
||||
|
||||
## 📊 Current State Analysis
|
||||
|
||||
### App Frameworks & Styling
|
||||
|
||||
| App | Framework | Styling | UI Components | Theme System |
|
||||
|-----|-----------|---------|---------------|--------------|
|
||||
| **Mobile** | React Native (Expo) | NativeWind (Tailwind) | @memoro/mobile-ui (17 components) | ✅ Advanced (3 variants, light/dark) |
|
||||
| **Web** | SvelteKit | Tailwind CSS v4 | Custom Svelte (4 components) | ❌ None (hardcoded colors) |
|
||||
| **Landing** | Astro | Tailwind CSS v3 | Custom Astro (4 components) | ❌ None (hardcoded colors) |
|
||||
|
||||
### Current Color Usage
|
||||
|
||||
#### Mobile App (`apps/mobile/`)
|
||||
**Advanced Theme System:**
|
||||
```typescript
|
||||
// constants/colors.ts + constants/themes/
|
||||
{
|
||||
background: '#000000',
|
||||
surface: '#242424',
|
||||
primary: { default: '#818cf8', hover: '#a5b4fc', ... },
|
||||
text: { primary: '#f3f4f6', secondary: '#d1d5db', ... },
|
||||
// + sunset, ocean, default variants
|
||||
}
|
||||
```
|
||||
|
||||
#### Web App (`apps/web/`)
|
||||
**Hardcoded in Components:**
|
||||
```svelte
|
||||
<!-- Button.svelte -->
|
||||
primary: 'bg-blue-600 text-white hover:bg-blue-700'
|
||||
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300'
|
||||
```
|
||||
|
||||
#### Landing Page (`apps/landing/`)
|
||||
**Hardcoded in Components:**
|
||||
```astro
|
||||
<!-- Hero.astro -->
|
||||
<div class="bg-gradient-to-br from-purple-900/20 via-gray-900 to-pink-900/20">
|
||||
<span class="bg-gradient-to-r from-purple-400 via-pink-400 to-purple-400">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Unification Goals
|
||||
|
||||
### What We Want to Achieve
|
||||
|
||||
1. **Visual Consistency** - Same colors, spacing, and typography across all apps
|
||||
2. **Single Source of Truth** - One place to define design decisions
|
||||
3. **Easy Updates** - Change brand colors once, apply everywhere
|
||||
4. **Theme Support** - All apps support light/dark mode + theme variants
|
||||
5. **Framework Independence** - Works in React Native, Svelte, and Astro
|
||||
|
||||
### What We DON'T Want
|
||||
|
||||
- ❌ Shared UI components (not possible due to framework differences)
|
||||
- ❌ Complex build systems
|
||||
- ❌ Runtime overhead
|
||||
- ❌ Rewriting everything from scratch
|
||||
|
||||
---
|
||||
|
||||
## 💡 Proposed Solution: Shared Design Tokens
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
picture/
|
||||
├── packages/
|
||||
│ ├── design-tokens/ # ← NEW: Shared design system
|
||||
│ │ ├── src/
|
||||
│ │ │ ├── colors.ts # Color definitions
|
||||
│ │ │ ├── spacing.ts # Spacing scale
|
||||
│ │ │ ├── typography.ts # Font definitions
|
||||
│ │ │ ├── shadows.ts # Shadow styles
|
||||
│ │ │ ├── animations.ts # Animation timings
|
||||
│ │ │ ├── themes/
|
||||
│ │ │ │ ├── index.ts # Theme exports
|
||||
│ │ │ │ ├── default.ts # Default theme
|
||||
│ │ │ │ ├── sunset.ts # Sunset variant
|
||||
│ │ │ │ └── ocean.ts # Ocean variant
|
||||
│ │ │ └── index.ts # Main export
|
||||
│ │ ├── tailwind/
|
||||
│ │ │ └── preset.js # Tailwind preset
|
||||
│ │ ├── native/
|
||||
│ │ │ └── theme.ts # React Native helpers
|
||||
│ │ ├── package.json
|
||||
│ │ └── README.md
|
||||
│ ├── mobile-ui/ # React Native components
|
||||
│ └── shared/ # Backend logic
|
||||
└── apps/
|
||||
├── mobile/ ✅ Uses design-tokens + mobile-ui
|
||||
├── web/ ✅ Uses design-tokens + Svelte components
|
||||
└── landing/ ✅ Uses design-tokens + Astro components
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Package Structure: `@memoro/design-tokens`
|
||||
|
||||
### 1. Colors (`src/colors.ts`)
|
||||
|
||||
**Single source of truth for all colors:**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* @memoro/design-tokens
|
||||
* Central color definitions for all memoro apps
|
||||
*/
|
||||
|
||||
export const baseColors = {
|
||||
// Neutrals (dark mode focused)
|
||||
black: '#000000',
|
||||
gray: {
|
||||
50: '#f9fafb',
|
||||
100: '#f3f4f6',
|
||||
200: '#e5e7eb',
|
||||
300: '#d1d5db',
|
||||
400: '#9ca3af',
|
||||
500: '#6b7280',
|
||||
600: '#4b5563',
|
||||
700: '#374151',
|
||||
800: '#1f2937',
|
||||
900: '#111827',
|
||||
950: '#0a0a0a',
|
||||
},
|
||||
|
||||
// Brand colors
|
||||
indigo: {
|
||||
300: '#a5b4fc',
|
||||
400: '#818cf8',
|
||||
500: '#6366f1',
|
||||
600: '#4f46e5',
|
||||
},
|
||||
|
||||
purple: {
|
||||
300: '#d8b4fe',
|
||||
400: '#c084fc',
|
||||
500: '#a855f7',
|
||||
600: '#9333ea',
|
||||
900: '#581c87',
|
||||
},
|
||||
|
||||
pink: {
|
||||
400: '#f472b6',
|
||||
500: '#ec4899',
|
||||
},
|
||||
|
||||
// Status
|
||||
red: {
|
||||
500: '#ef4444',
|
||||
600: '#dc2626',
|
||||
},
|
||||
emerald: {
|
||||
500: '#10b981',
|
||||
},
|
||||
amber: {
|
||||
500: '#f59e0b',
|
||||
},
|
||||
blue: {
|
||||
600: '#2563eb',
|
||||
700: '#1d4ed8',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const semanticColors = {
|
||||
dark: {
|
||||
background: baseColors.black,
|
||||
surface: '#242424',
|
||||
elevated: '#2a2a2a',
|
||||
border: '#383838',
|
||||
input: '#1f1f1f',
|
||||
|
||||
text: {
|
||||
primary: baseColors.gray[100],
|
||||
secondary: baseColors.gray[300],
|
||||
tertiary: baseColors.gray[400],
|
||||
disabled: baseColors.gray[500],
|
||||
},
|
||||
|
||||
primary: {
|
||||
default: baseColors.indigo[400],
|
||||
hover: baseColors.indigo[300],
|
||||
active: baseColors.indigo[500],
|
||||
},
|
||||
|
||||
danger: baseColors.red[500],
|
||||
success: baseColors.emerald[500],
|
||||
warning: baseColors.amber[500],
|
||||
},
|
||||
|
||||
light: {
|
||||
background: '#ffffff',
|
||||
surface: baseColors.gray[50],
|
||||
elevated: '#ffffff',
|
||||
border: baseColors.gray[200],
|
||||
input: '#ffffff',
|
||||
|
||||
text: {
|
||||
primary: baseColors.gray[900],
|
||||
secondary: baseColors.gray[600],
|
||||
tertiary: baseColors.gray[500],
|
||||
disabled: baseColors.gray[400],
|
||||
},
|
||||
|
||||
primary: {
|
||||
default: baseColors.blue[600],
|
||||
hover: baseColors.blue[700],
|
||||
active: baseColors.indigo[600],
|
||||
},
|
||||
|
||||
danger: baseColors.red[600],
|
||||
success: baseColors.emerald[500],
|
||||
warning: baseColors.amber[500],
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type SemanticColors = typeof semanticColors.dark;
|
||||
```
|
||||
|
||||
### 2. Spacing (`src/spacing.ts`)
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Spacing scale - follows Tailwind convention
|
||||
* All values in pixels for easy conversion
|
||||
*/
|
||||
export const spacing = {
|
||||
0: 0,
|
||||
1: 4, // 0.25rem
|
||||
2: 8, // 0.5rem
|
||||
3: 12, // 0.75rem
|
||||
4: 16, // 1rem
|
||||
5: 20, // 1.25rem
|
||||
6: 24, // 1.5rem
|
||||
8: 32, // 2rem
|
||||
10: 40, // 2.5rem
|
||||
12: 48, // 3rem
|
||||
16: 64, // 4rem
|
||||
20: 80, // 5rem
|
||||
24: 96, // 6rem
|
||||
} as const;
|
||||
|
||||
export const borderRadius = {
|
||||
none: 0,
|
||||
sm: 4,
|
||||
md: 8,
|
||||
lg: 12,
|
||||
xl: 16,
|
||||
'2xl': 24,
|
||||
full: 9999,
|
||||
} as const;
|
||||
```
|
||||
|
||||
### 3. Typography (`src/typography.ts`)
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Typography scale
|
||||
*/
|
||||
export const fontSizes = {
|
||||
xs: 12,
|
||||
sm: 14,
|
||||
base: 16,
|
||||
lg: 18,
|
||||
xl: 20,
|
||||
'2xl': 24,
|
||||
'3xl': 30,
|
||||
'4xl': 36,
|
||||
'5xl': 48,
|
||||
'6xl': 60,
|
||||
'7xl': 72,
|
||||
'8xl': 96,
|
||||
} as const;
|
||||
|
||||
export const fontWeights = {
|
||||
regular: '400',
|
||||
medium: '500',
|
||||
semibold: '600',
|
||||
bold: '700',
|
||||
} as const;
|
||||
|
||||
export const lineHeights = {
|
||||
tight: 1.2,
|
||||
normal: 1.5,
|
||||
relaxed: 1.75,
|
||||
} as const;
|
||||
```
|
||||
|
||||
### 4. Theme Variants (`src/themes/`)
|
||||
|
||||
```typescript
|
||||
// src/themes/default.ts
|
||||
import { baseColors, semanticColors } from '../colors';
|
||||
|
||||
export const defaultTheme = {
|
||||
name: 'default' as const,
|
||||
displayName: 'Default',
|
||||
colors: {
|
||||
light: semanticColors.light,
|
||||
dark: semanticColors.dark,
|
||||
},
|
||||
};
|
||||
|
||||
// src/themes/sunset.ts
|
||||
export const sunsetTheme = {
|
||||
name: 'sunset' as const,
|
||||
displayName: 'Sunset',
|
||||
colors: {
|
||||
light: { ...semanticColors.light },
|
||||
dark: {
|
||||
...semanticColors.dark,
|
||||
primary: {
|
||||
default: '#fb923c', // orange-400
|
||||
hover: '#fdba74', // orange-300
|
||||
active: '#f97316', // orange-500
|
||||
},
|
||||
secondary: {
|
||||
default: '#f472b6', // pink-400
|
||||
hover: '#f9a8d4', // pink-300
|
||||
active: '#ec4899', // pink-500
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// src/themes/ocean.ts
|
||||
export const oceanTheme = {
|
||||
name: 'ocean' as const,
|
||||
displayName: 'Ocean',
|
||||
colors: {
|
||||
light: { ...semanticColors.light },
|
||||
dark: {
|
||||
...semanticColors.dark,
|
||||
primary: {
|
||||
default: '#38bdf8', // sky-400
|
||||
hover: '#7dd3fc', // sky-300
|
||||
active: '#0ea5e9', // sky-500
|
||||
},
|
||||
secondary: {
|
||||
default: '#34d399', // emerald-400
|
||||
hover: '#6ee7b7', // emerald-300
|
||||
active: '#10b981', // emerald-500
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// src/themes/index.ts
|
||||
export * from './default';
|
||||
export * from './sunset';
|
||||
export * from './ocean';
|
||||
|
||||
export const themes = {
|
||||
default: defaultTheme,
|
||||
sunset: sunsetTheme,
|
||||
ocean: oceanTheme,
|
||||
} as const;
|
||||
|
||||
export type ThemeVariant = keyof typeof themes;
|
||||
```
|
||||
|
||||
### 5. Tailwind Preset (`tailwind/preset.js`)
|
||||
|
||||
```javascript
|
||||
// tailwind/preset.js
|
||||
const { semanticColors, spacing, borderRadius, fontSizes } = require('../dist');
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// Semantic colors for both light and dark
|
||||
background: 'var(--color-background)',
|
||||
surface: 'var(--color-surface)',
|
||||
elevated: 'var(--color-elevated)',
|
||||
border: 'var(--color-border)',
|
||||
|
||||
primary: {
|
||||
DEFAULT: 'var(--color-primary)',
|
||||
hover: 'var(--color-primary-hover)',
|
||||
active: 'var(--color-primary-active)',
|
||||
},
|
||||
|
||||
// Direct color access for Tailwind
|
||||
dark: {
|
||||
bg: semanticColors.dark.background,
|
||||
surface: semanticColors.dark.surface,
|
||||
elevated: semanticColors.dark.elevated,
|
||||
border: semanticColors.dark.border,
|
||||
input: semanticColors.dark.input,
|
||||
},
|
||||
},
|
||||
spacing,
|
||||
borderRadius,
|
||||
fontSize: fontSizes,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 6. React Native Helpers (`native/theme.ts`)
|
||||
|
||||
```typescript
|
||||
// native/theme.ts
|
||||
import { semanticColors } from '../src/colors';
|
||||
import { spacing, borderRadius } from '../src/spacing';
|
||||
|
||||
/**
|
||||
* Convert design tokens to React Native theme
|
||||
*/
|
||||
export function createNativeTheme(mode: 'light' | 'dark', variant: string = 'default') {
|
||||
const colors = semanticColors[mode];
|
||||
|
||||
return {
|
||||
colors,
|
||||
spacing,
|
||||
borderRadius,
|
||||
// React Native shadow helpers
|
||||
shadows: {
|
||||
sm: {
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
},
|
||||
md: {
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
elevation: 4,
|
||||
},
|
||||
lg: {
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 8,
|
||||
elevation: 8,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Implementation Per App
|
||||
|
||||
### 1. Mobile App (`@picture/mobile`)
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
# Add to package.json dependencies
|
||||
"@memoro/design-tokens": "workspace:*"
|
||||
```
|
||||
|
||||
**Usage in Theme Store:**
|
||||
```typescript
|
||||
// store/themeStore.ts
|
||||
import { themes, semanticColors } from '@memoro/design-tokens';
|
||||
import { createNativeTheme } from '@memoro/design-tokens/native';
|
||||
|
||||
export const useThemeStore = create<ThemeState>((set) => ({
|
||||
variant: 'default',
|
||||
mode: 'dark',
|
||||
|
||||
theme: createNativeTheme('dark', 'default'),
|
||||
|
||||
setVariant: (variant) => {
|
||||
const theme = themes[variant];
|
||||
// Apply theme colors
|
||||
set({ variant, theme: createNativeTheme(mode, variant) });
|
||||
},
|
||||
}));
|
||||
```
|
||||
|
||||
**Update Tailwind Config:**
|
||||
```javascript
|
||||
// tailwind.config.js
|
||||
module.exports = {
|
||||
presets: [
|
||||
require('nativewind/preset'),
|
||||
require('@memoro/design-tokens/tailwind/preset'),
|
||||
],
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
**Migrate Components:**
|
||||
```typescript
|
||||
// Before (hardcoded)
|
||||
const Button = () => (
|
||||
<View style={{ backgroundColor: '#818cf8' }}>
|
||||
|
||||
// After (using tokens)
|
||||
import { useTheme } from '~/contexts/ThemeContext';
|
||||
|
||||
const Button = () => {
|
||||
const { theme } = useTheme();
|
||||
return (
|
||||
<View style={{ backgroundColor: theme.colors.primary.default }}>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Web App (`@picture/web`)
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
# Add to package.json
|
||||
"@memoro/design-tokens": "workspace:*"
|
||||
```
|
||||
|
||||
**Update Tailwind (using preset):**
|
||||
```javascript
|
||||
// Web uses Tailwind v4, so we adapt the approach
|
||||
// apps/web/src/app.css
|
||||
@import 'tailwindcss';
|
||||
@import '@memoro/design-tokens/tailwind/tokens.css'; /* New file we create */
|
||||
|
||||
@theme {
|
||||
/* Import design tokens as CSS variables */
|
||||
--color-background: var(--token-dark-background);
|
||||
--color-surface: var(--token-dark-surface);
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
**Create Theme Context (NEW):**
|
||||
```typescript
|
||||
// src/lib/stores/theme.ts
|
||||
import { writable } from 'svelte/store';
|
||||
import { themes } from '@memoro/design-tokens';
|
||||
|
||||
type ThemeMode = 'light' | 'dark';
|
||||
type ThemeVariant = 'default' | 'sunset' | 'ocean';
|
||||
|
||||
export const themeMode = writable<ThemeMode>('dark');
|
||||
export const themeVariant = writable<ThemeVariant>('default');
|
||||
|
||||
export const currentTheme = derived(
|
||||
[themeMode, themeVariant],
|
||||
([$mode, $variant]) => themes[$variant].colors[$mode]
|
||||
);
|
||||
```
|
||||
|
||||
**Update Components:**
|
||||
```svelte
|
||||
<!-- Button.svelte - Before -->
|
||||
<script>
|
||||
const variants = {
|
||||
primary: 'bg-blue-600 text-white hover:bg-blue-700',
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Button.svelte - After -->
|
||||
<script>
|
||||
import { currentTheme } from '$lib/stores/theme';
|
||||
|
||||
// Use CSS variables from design tokens
|
||||
const variants = {
|
||||
primary: 'bg-[var(--color-primary)] text-white hover:bg-[var(--color-primary-hover)]',
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Landing Page (`@picture/landing`)
|
||||
|
||||
**Install:**
|
||||
```bash
|
||||
"@memoro/design-tokens": "workspace:*"
|
||||
```
|
||||
|
||||
**Update Tailwind:**
|
||||
```javascript
|
||||
// tailwind.config.mjs
|
||||
import designTokensPreset from '@memoro/design-tokens/tailwind/preset';
|
||||
|
||||
export default {
|
||||
presets: [designTokensPreset],
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
**Update Components:**
|
||||
```astro
|
||||
<!-- Hero.astro - Before -->
|
||||
<div class="bg-gradient-to-br from-purple-900/20 via-gray-900 to-pink-900/20">
|
||||
|
||||
<!-- Hero.astro - After -->
|
||||
<div class="bg-gradient-to-br from-purple-900/20 via-[var(--color-background)] to-pink-900/20">
|
||||
<span class="text-[var(--color-primary)]">Create Stunning Images</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Migration Strategy
|
||||
|
||||
### Phase 1: Foundation (Week 1) ✅
|
||||
- [x] Create `packages/design-tokens/` package
|
||||
- [x] Extract colors from mobile app
|
||||
- [x] Add spacing, typography, shadows
|
||||
- [x] Create theme variants (default, sunset, ocean)
|
||||
- [x] Build Tailwind preset
|
||||
- [x] Build React Native helpers
|
||||
- [x] Write documentation
|
||||
|
||||
### Phase 2: Mobile App (Week 2)
|
||||
- [ ] Install design tokens package
|
||||
- [ ] Update theme store to use tokens
|
||||
- [ ] Update Tailwind config to use preset
|
||||
- [ ] Migrate `@memoro/mobile-ui` components
|
||||
- [ ] Test theme switching
|
||||
- [ ] Verify all 17 components work
|
||||
|
||||
### Phase 3: Web App (Week 3)
|
||||
- [ ] Install design tokens package
|
||||
- [ ] Create theme store
|
||||
- [ ] Add CSS variables
|
||||
- [ ] Update Tailwind config
|
||||
- [ ] Migrate Button, Card, Input, Modal components
|
||||
- [ ] Add theme switcher UI
|
||||
- [ ] Test across pages
|
||||
|
||||
### Phase 4: Landing Page (Week 4)
|
||||
- [ ] Install design tokens package
|
||||
- [ ] Update Tailwind config
|
||||
- [ ] Migrate Hero, CTA, Features, Footer
|
||||
- [ ] (Optional) Add theme switcher
|
||||
- [ ] Test responsiveness
|
||||
|
||||
### Phase 5: Documentation (Ongoing)
|
||||
- [ ] Usage guides per framework
|
||||
- [ ] Migration checklists
|
||||
- [ ] Design token reference
|
||||
- [ ] Contributing guidelines
|
||||
|
||||
---
|
||||
|
||||
## ✅ Success Metrics
|
||||
|
||||
**Visual Consistency:**
|
||||
- [ ] All apps use same color palette
|
||||
- [ ] Same spacing scale across apps
|
||||
- [ ] Consistent typography
|
||||
|
||||
**Developer Experience:**
|
||||
- [ ] One place to update colors
|
||||
- [ ] Type-safe tokens in TypeScript
|
||||
- [ ] Easy to add new themes
|
||||
|
||||
**Maintainability:**
|
||||
- [ ] Single source of truth for design
|
||||
- [ ] Version controlled design decisions
|
||||
- [ ] Documented usage patterns
|
||||
|
||||
**Performance:**
|
||||
- [ ] No runtime overhead
|
||||
- [ ] Compile-time only package
|
||||
- [ ] Small bundle size impact
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Example: Adding New Theme
|
||||
|
||||
```typescript
|
||||
// packages/design-tokens/src/themes/forest.ts
|
||||
export const forestTheme = {
|
||||
name: 'forest' as const,
|
||||
displayName: 'Forest',
|
||||
colors: {
|
||||
dark: {
|
||||
...semanticColors.dark,
|
||||
primary: {
|
||||
default: '#22c55e', // green-500
|
||||
hover: '#4ade80', // green-400
|
||||
active: '#16a34a', // green-600
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Add to index
|
||||
export * from './forest';
|
||||
```
|
||||
|
||||
Then ALL apps automatically support the new theme! 🎉
|
||||
|
||||
---
|
||||
|
||||
## 📚 Alternative Approaches Considered
|
||||
|
||||
### ❌ Option 1: Shared React Components
|
||||
**Rejected:** React Native components don't work on web
|
||||
|
||||
### ❌ Option 2: Headless UI + Adapters
|
||||
**Rejected:** Too complex, high maintenance overhead
|
||||
|
||||
### ❌ Option 3: CSS-in-JS Runtime
|
||||
**Rejected:** Performance impact, bundle size
|
||||
|
||||
### ✅ Option 4: Design Tokens (CHOSEN)
|
||||
**Why:** Compile-time, framework-agnostic, minimal overhead
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Next Steps
|
||||
|
||||
1. **Review this proposal** - Feedback on approach?
|
||||
2. **Create `@memoro/design-tokens` package** - Start with Phase 1
|
||||
3. **Test in mobile app first** - Validate approach
|
||||
4. **Roll out to web & landing** - Iterate based on learnings
|
||||
5. **Document patterns** - Make it easy for future developers
|
||||
|
||||
---
|
||||
|
||||
## 📞 Questions to Answer
|
||||
|
||||
1. **Theme variants:** Keep default/sunset/ocean? Add more?
|
||||
2. **Light mode:** Priority level? All apps or mobile-only?
|
||||
3. **Animation tokens:** Need shared animation configs?
|
||||
4. **Accessibility:** WCAG contrast ratios validated?
|
||||
5. **Version strategy:** How to handle breaking changes?
|
||||
|
||||
---
|
||||
|
||||
**Status:** 📝 Awaiting review
|
||||
**Next:** Create design tokens package prototype
|
||||
Loading…
Add table
Add a link
Reference in a new issue