@studyjoyful/shared
v1.0.12
Published
Shared code for StudyJoyful Web and App (i18n, constants, types, utils)
Downloads
74
Maintainers
Readme
@studyjoyful/shared
Shared code for StudyJoyful Web and App.
šÆ Design Principles
i18n: Single Source of Truth
ā ļø Critical: This package is the ONLY source of translations. Web and App do NOT have their own
locales/directories.
| Principle | Description | | ----------------- | --------------------------------------- | | Single Source | All translations here, nowhere else | | English Only | Singapore market = English only | | Modular | Split by feature (auth, chat, tasks...) | | Shared | Web + App import from this package |
š¦ Modules
| Module | Description | Exports |
| ------------- | -------------------- | ----------------------------------------- |
| i18n | Internationalization | resources, namespaces, defaultNS |
| constants | Shared constants | EXAMPLES_BY_GRADE, getExamplesByGrade |
| types | Type definitions | ChildGrade, Subject, Example |
| utils | Utility functions | randomSelect, shuffle |
š Usage
Installation (yarn link)
# In this package
cd studyjoyful-shared
yarn link
# In Web
cd ../studyjoyful-web
yarn link "@studyjoyful/shared"
# In App
cd ../studyjoyful-app
yarn link "@studyjoyful/shared"App Metro Config
The App requires special Metro configuration:
// metro.config.js
const sharedPackagePath = path.resolve(__dirname, "../studyjoyful-shared");
config.watchFolders = [sharedPackagePath];
config.resolver.nodeModulesPaths = [
path.resolve(__dirname, "node_modules"),
path.resolve(sharedPackagePath, "node_modules"),
];
const ALIASES = {
"@studyjoyful/shared": sharedPackagePath + "/src",
};Import Examples
// i18n
import { resources, namespaces, defaultNS } from "@studyjoyful/shared";
// Constants
import { EXAMPLES_BY_GRADE, getExamplesByGrade } from "@studyjoyful/shared";
// Types
import type { ChildGrade, Subject, Example } from "@studyjoyful/shared";
// Utils
import { randomSelect, shuffle } from "@studyjoyful/shared";š Structure
src/
āāā index.ts # Main exports
āāā i18n/
ā āāā index.ts
ā āāā locales/
ā āāā en/ # English translations
ā āāā common.json
ā āāā auth.json
ā āāā chat.json
ā āāā tasks.json
ā āāā learning.json
ā āāā profile.json
ā āāā errors.json
ā āāā sidebar.json
āāā constants/
ā āāā index.ts
ā āāā examples.ts # Learning examples
āāā types/
ā āāā index.ts
ā āāā child.ts # ChildGrade, Subject
ā āāā common.ts # PaginationParams
āāā utils/
āāā index.ts
āāā random.ts # randomSelect, shuffleš§ Development
# Type check
npx tsc --noEmit
# After changes, test in both:
# 1. Web (hot reload)
# 2. App (metro refresh)š Adding New Content
- Create file in appropriate module
- Export from module's
index.ts - Re-export from main
src/index.ts - Test in both Web and App
š Adding Translations
DO:
# Add to this package
src/i18n/locales/en/auth.json # ā
CorrectDON'T:
# Never create locales in consumer projects
studyjoyful-app/locales/ # ā WRONG
studyjoyful-web/locales/ # ā WRONGTranslation File Structure
// src/i18n/locales/en/auth.json
{
"welcome": {
"title": "StudyJoyful",
"subtitle": "Turn homework into 10-minute learning games",
"getStarted": "Get Started"
},
"errors": {
"signInFailed": "Sign In Failed",
"tryAgain": "Please try again"
}
}Usage in Consumer Projects
// lib/i18n.ts (in Web or App)
import { resources, namespaces, defaultNS } from "@studyjoyful/shared";
// Component
import { useTranslation } from "react-i18next";
function WelcomeScreen() {
const { t } = useTranslation("auth");
return <Text>{t("welcome.title")}</Text>;
}Package: @studyjoyful/shared
Version: 1.0.0
Consumers: studyjoyful-web, studyjoyful-app
Language: English only (Singapore market)