feat: add ActionTools component documentation and update navigation links
This commit is contained in:
@@ -114,10 +114,42 @@ apps/web/src/apps/modules/booking/
|
||||
└── en/booking.json
|
||||
```
|
||||
|
||||
### Lazy Loading & Type Safety
|
||||
Register the namespace when the component mounts. To get native TypeScript autocomplete for nested keys (e.g., `header.title`), augment the global `react-i18next` types.
|
||||
### Namespace Registration & Context
|
||||
|
||||
To prevent unnecessary React re-renders and ensure dictionaries are loaded before the first paint, translations are registered at the module scope using `registerModuleNamespace`.
|
||||
|
||||
**1. Register the Namespace in the Module Factory:**
|
||||
|
||||
Call `registerModuleNamespace` at the top level of your module factory (e.g., `index.tsx`). This function is idempotent and safe to call outside the React render cycle. The namespace provided must match the `translationNamespace` defined in your module configuration.
|
||||
|
||||
```tsx
|
||||
// apps/web/src/apps/modules/booking/presentation/factory/index.tsx
|
||||
import { EnterpriseModuleProvider } from '@repo/ui/foundations';
|
||||
import { registerModuleNamespace } from '@repo/core-i18n';
|
||||
import { BookingModuleConfig } from '../../domain/constants';
|
||||
|
||||
import bookingId from '../locales/id/booking.json';
|
||||
import bookingEn from '../locales/en/booking.json';
|
||||
|
||||
// Called once at import time — safe, idempotent, outside React render cycle.
|
||||
registerModuleNamespace(BookingModuleConfig.translationNamespace, {
|
||||
id: bookingId,
|
||||
en: bookingEn,
|
||||
});
|
||||
|
||||
export default function BookingModule() {
|
||||
return (
|
||||
<EnterpriseModuleProvider config={BookingModuleConfig}>
|
||||
{/* Routes and Pages */}
|
||||
</EnterpriseModuleProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**2. Augment Types for Autocomplete:**
|
||||
|
||||
To get native TypeScript autocomplete for nested keys (e.g., `header.title`), augment the global `react-i18next` types.
|
||||
|
||||
**1. Augment Types:**
|
||||
```ts
|
||||
// apps/web/src/types/i18next.d.ts
|
||||
import 'react-i18next';
|
||||
@@ -132,26 +164,31 @@ declare module 'react-i18next' {
|
||||
}
|
||||
```
|
||||
|
||||
**2. Use in Component:**
|
||||
**3. Consume in Components:**
|
||||
|
||||
Inside your pages and components, use `useEnterpriseModuleTranslationContext()` instead of the raw `useTranslation` hook. The context automatically scopes the `t` function to your module's namespace and the global `common` namespace.
|
||||
|
||||
> [!WARNING]
|
||||
> **Best Practice:** Do not hardcode the module namespace prefix (e.g., `t('booking:header.title')`) when using `useEnterpriseModuleTranslationContext`. The provider already scopes it. Simply use `t('header.title')`. You can still access global keys using the common prefix: `t('common:edit')`.
|
||||
|
||||
```tsx
|
||||
import { useEffect } from 'react';
|
||||
import { i18n, useTranslation } from '@repo/core-i18n';
|
||||
import bookingId from '../locales/id/booking.json';
|
||||
import bookingEn from '../locales/en/booking.json';
|
||||
// apps/web/src/apps/modules/booking/presentation/pages/booking.page.index.tsx
|
||||
import { Title } from '@repo/ui/components';
|
||||
import { useEnterpriseModuleTranslationContext } from '@repo/ui/foundations';
|
||||
|
||||
export default function BookingFeature() {
|
||||
const { t } = useTranslation(['common', 'booking']);
|
||||
export default function BookingPageIndex() {
|
||||
const { t } = useEnterpriseModuleTranslationContext();
|
||||
|
||||
useEffect(() => {
|
||||
i18n.addResourceBundle('id', 'booking', bookingId, true, false);
|
||||
i18n.addResourceBundle('en', 'booking', bookingEn, true, false);
|
||||
}, []);
|
||||
|
||||
return <h1>{t('booking:header.title')}</h1>; // Autocomplete works!
|
||||
return (
|
||||
<div>
|
||||
<Title>{t('title')}</Title> {/* Automatically resolves to booking:title */}
|
||||
<button>{t('common:edit')}</button> {/* Fallback to global common vocabulary */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**3. Dynamic Variables (Interpolation):**
|
||||
**4. Dynamic Variables (Interpolation):**
|
||||
```json
|
||||
// booking.json
|
||||
{
|
||||
@@ -162,7 +199,7 @@ export default function BookingFeature() {
|
||||
```
|
||||
```tsx
|
||||
// Inside component
|
||||
<h1>{t('booking:messages.welcome', { name: 'Firman', count: 5 })}</h1>
|
||||
<h1>{t('messages.welcome', { name: 'Firman', count: 5 })}</h1>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user