@gringow/gringow-react 0.0.8 → 0.2.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.
Files changed (2) hide show
  1. package/README.md +310 -44
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,90 +1,278 @@
1
1
  # @gringow/gringow-react
2
2
 
3
- React bindings for the Gringow AI powered translation engine. This package exposes a tiny React friendly wrapper on top of the core `@gringow/gringow` library so you can render translated template strings, consume cached translations, and switch languages at runtime.
3
+ [![npm version](https://img.shields.io/npm/v/@gringow/gringow-react)](https://www.npmjs.com/package/@gringow/gringow-react)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4
5
 
5
- ## Highlights
6
- - Declarative template strings via the `g` helper and a lightweight custom element
7
- - Client side cache bootstrap through `GringowStore` with either a static JSON URL or a Gringow IO token
8
- - Runtime language switching by dispatching the built in `LanguageChangeEvent`
9
- - Ships typed exports (`.d.ts`) and tree shakeable modules ready for modern bundlers
6
+ React bindings for Gringow AI-powered translations. Provides declarative template string translations with runtime language switching and smart caching. Built on [@gringow/gringow-shadow](https://www.npmjs.com/package/@gringow/gringow-shadow) Web Components.
7
+
8
+ ## Features
9
+
10
+ - ⚛️ **React 19+ Support** - Uses modern React features and hooks
11
+ - 🏷️ **Template Literal Syntax** - Translate with \`g\`Hello ${name}\`\`
12
+ - 🔄 **Runtime Language Switching** - Change languages without reload
13
+ - 💾 **Smart Caching** - Automatic cache lookup and fallback
14
+ - 🌐 **SSR Compatible** - Server-side rendering support
15
+ - 🎯 **Type-Safe** - Full TypeScript definitions included
10
16
 
11
17
  ## Installation
18
+
12
19
  ```bash
20
+ # Using pnpm
13
21
  pnpm add @gringow/gringow @gringow/gringow-react
14
- # npm install @gringow/gringow @gringow/gringow-react
15
- # yarn add @gringow/gringow @gringow/gringow-react
22
+
23
+ # Using npm
24
+ npm install @gringow/gringow @gringow/gringow-react
25
+
26
+ # Using yarn
27
+ yarn add @gringow/gringow @gringow/gringow-react
16
28
  ```
17
29
 
18
- ### Peer requirements
19
- - React 19 or newer
20
- - A cache produced by the core Gringow tooling (CLI, Vite plugin, or direct API usage)
30
+ ### Requirements
31
+
32
+ - **React 19+**
33
+ - **A Gringow cache file** (generated by [@gringow/cli](https://www.npmjs.com/package/@gringow/gringow-cli) or [@gringow/gringow-vite](https://www.npmjs.com/package/@gringow/gringow-vite))
34
+
35
+ ## Quick Start
21
36
 
22
- ## Quick start
23
- Register the custom element once on the client, configure the store, and then render translated strings with the `g`
24
- helper.
37
+ ### 1. Initialize Gringow (Client-Side)
25
38
 
26
39
  ```tsx
27
- // app-bootstrap.ts (client-only)
40
+ // app-bootstrap.tsx (client-only)
28
41
  import '@gringow/gringow-react/browser'
29
42
  import { GringowStore } from '@gringow/gringow-react/store'
30
43
 
44
+ // Configure store
31
45
  GringowStore.language = 'en-US'
32
46
  GringowStore.cacheUrl = '/gringow/gringow.json'
47
+
48
+ // Fetch cache once
33
49
  await GringowStore.fetchCache()
34
50
  ```
35
51
 
52
+ ### 2. Use Translations in Components
53
+
36
54
  ```tsx
37
55
  // Welcome.tsx
38
56
  import { g } from '@gringow/gringow-react'
39
57
 
40
58
  export function Welcome({ name }: { name: string }) {
41
- return <>{g`Hello ${name}, welcome back!`}</>
59
+ return (
60
+ <div>
61
+ <h1>{g`Hello ${name}, welcome back!`}</h1>
62
+ <p>{g`You have new messages`}</p>
63
+ </div>
64
+ )
42
65
  }
43
66
  ```
44
67
 
45
- The helper flattens the template string, looks up the cached translation by ID, and renders a `<g-gringow>` custom element wrapped in `React.Suspense`. Until the cache is available the original template literal is used as a fallback.
68
+ ### 3. Add Language Switcher
69
+
70
+ ```tsx
71
+ // LanguageSwitcher.tsx
72
+ import { changeLanguage } from '@gringow/gringow-react'
73
+
74
+ export function LanguageSwitcher() {
75
+ return (
76
+ <div>
77
+ <button onClick={() => changeLanguage('en-US')}>English</button>
78
+ <button onClick={() => changeLanguage('pt-BR')}>Português</button>
79
+ <button onClick={() => changeLanguage('fr-CA')}>Français</button>
80
+ </div>
81
+ )
82
+ }
83
+ ```
46
84
 
47
- > The `browser` entry registers the `<g-gringow>` element and wires it to `GringowStore`. Import it once per
48
- > application (typically in your client bootstrap).
85
+ ## Usage Examples
49
86
 
50
- ## Managing the translation cache
51
- The store can be fed from a static file or from a hosted endpoint. When not set programmatically, `cacheUrl` falls back
52
- to `<meta name="gringow-cache-url">` or `data-gringow-cache-url` on `<html>`, and `language` defaults to
53
- `document.documentElement.lang`.
87
+ ### Basic Translation
54
88
 
55
89
  ```tsx
56
- import { GringowStore } from '@gringow/gringow-react'
90
+ import { g } from '@gringow/gringow-react'
57
91
 
58
- // Static JSON generated by the CLI or Vite plugin
59
- GringowStore.cacheUrl = '/gringow/gringow.json'
92
+ function Greeting() {
93
+ return <h1>{g`Welcome to Gringow`}</h1>
94
+ }
95
+ ```
96
+
97
+ ### Dynamic Content
98
+
99
+ ```tsx
100
+ import { g } from '@gringow/gringow-react'
60
101
 
61
- // Or fetch from Gringow IO using a short lived token
62
- GringowStore.gringowIoToken = process.env.GRINGOW_IO_TOKEN!
102
+ function UserProfile({ user }: { user: { name: string; role: string } }) {
103
+ return (
104
+ <div>
105
+ {g`Hello ${user.name}!`}
106
+ {g`Your role: ${user.role}`}
107
+ </div>
108
+ )
109
+ }
63
110
  ```
64
111
 
65
- Call `GringowStore.fetchCache()` to force a refresh whenever you invalidate the cache.
112
+ ### Full Application Example
113
+
114
+ ```tsx
115
+ // main.tsx
116
+ import React from 'react'
117
+ import ReactDOM from 'react-dom/client'
118
+ import '@gringow/gringow-react/browser'
119
+ import { GringowStore } from '@gringow/gringow-react/store'
120
+ import App from './App'
121
+
122
+ // Bootstrap Gringow
123
+ async function init() {
124
+ GringowStore.cacheUrl = '/gringow/gringow.json'
125
+ GringowStore.language = document.documentElement.lang || 'en-US'
126
+ await GringowStore.fetchCache()
66
127
 
67
- ## Switching languages at runtime
68
- Dispatch the `LanguageChangeEvent` from anywhere in your app. All mounted Gringow translations react to the global event.
128
+ ReactDOM.createRoot(document.getElementById('root')!).render(
129
+ <React.StrictMode>
130
+ <App />
131
+ </React.StrictMode>
132
+ )
133
+ }
134
+
135
+ init()
136
+ ```
69
137
 
70
138
  ```tsx
71
- import { LanguageChangeEvent } from '@gringow/gringow-react'
139
+ // App.tsx
140
+ import { g, changeLanguage } from '@gringow/gringow-react'
141
+
142
+ export default function App() {
143
+ const [user] = React.useState({ name: 'Alice', unread: 5 })
72
144
 
73
- function changeLanguage(lang: string) {
74
- window.dispatchEvent(LanguageChangeEvent.create(lang))
145
+ return (
146
+ <div>
147
+ <nav>
148
+ <button onClick={() => changeLanguage('en-US')}>EN</button>
149
+ <button onClick={() => changeLanguage('pt-BR')}>PT</button>
150
+ <button onClick={() => changeLanguage('es-ES')}>ES</button>
151
+ </nav>
152
+
153
+ <main>
154
+ <h1>{g`Welcome ${user.name}!`}</h1>
155
+ <p>{g`You have ${user.unread} unread messages`}</p>
156
+ <button>{g`Mark all as read`}</button>
157
+ </main>
158
+ </div>
159
+ )
75
160
  }
76
161
  ```
77
162
 
78
- ## API reference
79
- - `g(strings, ...values)` returns a `<g-gringow>` element keyed by the flattened template string.
80
- - `GringowStore` singleton exposes:
81
- - `language` getter/setter (defaults to `<html lang>`)
82
- - `cacheUrl` setter (fallback to `<meta name="gringow-cache-url">` or `data-gringow-cache-url`)
83
- - `fetchCache()` to load the cache once (throws if URL or language are missing)
84
- - `getCacheItem(cacheId)` to resolve a translation for the current language, falling back to the original string
85
- - `cache` getter with the resolved cache object (`Record<cacheId, GringowCacheItem>`)
86
- - `LanguageChangeEvent` class with `EVENT_NAME` constant and `create(lang)` helper
87
- - `changeLanguage(lang)` dispatches the language change event for convenience
163
+ ### With Vite
164
+
165
+ ```tsx
166
+ // vite.config.ts
167
+ import { defineConfig } from 'vite'
168
+ import react from '@vitejs/plugin-react'
169
+ import { GringowVitePlugin } from '@gringow/gringow-vite'
170
+
171
+ export default defineConfig({
172
+ plugins: [
173
+ react(),
174
+ GringowVitePlugin()
175
+ ]
176
+ })
177
+ ```
178
+
179
+ ## API Reference
180
+
181
+ ### `g` Template Tag
182
+
183
+ Main translation function using tagged template literals.
184
+
185
+ ```typescript
186
+ function g(strings: TemplateStringsArray, ...values: unknown[]): ReactNode
187
+ ```
188
+
189
+ **Example:**
190
+ ```tsx
191
+ {g`Hello ${name}!`}
192
+ {g`You have ${count} messages`}
193
+ ```
194
+
195
+ The `g` helper:
196
+ 1. Flattens the template string
197
+ 2. Creates a cache ID via content hashing
198
+ 3. Returns a `<g-gringow>` custom element
199
+ 4. Falls back to original string if cache unavailable
200
+
201
+ ### GringowStore
202
+
203
+ Singleton store for managing translation cache and language state.
204
+
205
+ #### Properties
206
+
207
+ ```typescript
208
+ // Active language (defaults to document.documentElement.lang)
209
+ GringowStore.language: string | null
210
+
211
+ // Cache file URL
212
+ GringowStore.cacheUrl: string | null
213
+
214
+ // Loaded cache object
215
+ GringowStore.cache: GringowCache | null
216
+ ```
217
+
218
+ #### Methods
219
+
220
+ ```typescript
221
+ // Fetch and cache translations
222
+ await GringowStore.fetchCache(): Promise<void>
223
+
224
+ // Get translation for specific cache ID
225
+ GringowStore.getCacheItem(cacheId: string): string | null
226
+
227
+ // Manually set cache
228
+ GringowStore.setCache(cache: GringowCache): void
229
+ ```
230
+
231
+ #### Configuration Fallbacks
232
+
233
+ `cacheUrl` resolution order:
234
+ 1. `GringowStore.cacheUrl` (programmatic)
235
+ 2. `<meta name="gringow-cache-url" content="/path">`
236
+ 3. `<html data-gringow-cache-url="/path">`
237
+
238
+ ### changeLanguage()
239
+
240
+ Convenience function for language switching.
241
+
242
+ ```typescript
243
+ function changeLanguage(lang: string): void
244
+ ```
245
+
246
+ **Example:**
247
+ ```tsx
248
+ <button onClick={() => changeLanguage('pt-BR')}>Português</button>
249
+ ```
250
+
251
+ Dispatches a global `LanguageChangeEvent` that updates all mounted components.
252
+
253
+ ### LanguageChangeEvent
254
+
255
+ Custom event for language changes.
256
+
257
+ ```typescript
258
+ class LanguageChangeEvent extends CustomEvent<{ lang: string }>
259
+
260
+ // Constants
261
+ LanguageChangeEvent.EVENT_NAME: 'gringow:language-change'
262
+
263
+ // Factory method
264
+ LanguageChangeEvent.create(lang: string): LanguageChangeEvent
265
+ ```
266
+
267
+ **Manual usage:**
268
+ ```tsx
269
+ window.dispatchEvent(LanguageChangeEvent.create('fr-CA'))
270
+
271
+ // Listen for changes
272
+ window.addEventListener(LanguageChangeEvent.EVENT_NAME, (event) => {
273
+ console.log('Language changed to:', event.detail.lang)
274
+ })
275
+ ```
88
276
 
89
277
  ## Development scripts
90
278
  ```bash
@@ -94,3 +282,81 @@ pnpm run watch # Rebuild on changes during local development
94
282
 
95
283
  ## License
96
284
  MIT © Renato Gaspar
285
+
286
+ ## How It Works
287
+
288
+ 1. **Template Literal** - `g` tag flattens strings and generates cache IDs
289
+ 2. **Custom Element** - Returns `<g-gringow>` Web Component (from shadow package)
290
+ 3. **Cache Lookup** - Component queries `GringowStore` for translations
291
+ 4. **Fallback** - Shows original text if cache unavailable or SSR
292
+ 5. **Reactivity** - Updates automatically on `LanguageChangeEvent`
293
+
294
+ ## SSR Support
295
+
296
+ The package handles server-side rendering gracefully:
297
+
298
+ ```tsx
299
+ // Server renders original text
300
+ {g`Hello ${name}`} // Outputs: "Hello Alice"
301
+
302
+ // Client hydrates and replaces with translation
303
+ {g`Hello ${name}`} // Outputs: "Olá Alice" (if pt-BR)
304
+ ```
305
+
306
+ The `<g-gringow>` element only translates on the client after cache loads.
307
+
308
+ ## Module Exports
309
+
310
+ ```typescript
311
+ // Main export
312
+ import { g, changeLanguage, LanguageChangeEvent } from '@gringow/gringow-react'
313
+
314
+ // Store export
315
+ import { GringowStore } from '@gringow/gringow-react/store'
316
+
317
+ // Browser initialization (import once)
318
+ import '@gringow/gringow-react/browser'
319
+ ```
320
+
321
+ ## Development
322
+
323
+ ```bash
324
+ # Install dependencies
325
+ pnpm install
326
+
327
+ # Build the package
328
+ pnpm run build
329
+
330
+ # Watch mode
331
+ pnpm run watch
332
+ ```
333
+
334
+ ## Best Practices
335
+
336
+ 1. **Import browser module once** - Do it in your app's entry point
337
+ 2. **Fetch cache early** - Call `GringowStore.fetchCache()` before rendering
338
+ 3. **Use Vite plugin** - Automatically extracts translations during build
339
+ 4. **Keep fallbacks** - Original strings serve as loading state
340
+ 5. **Cache versioning** - Bust cache when translations update
341
+
342
+ ## Related Packages
343
+
344
+ - **[@gringow/gringow](https://www.npmjs.com/package/@gringow/gringow)** - Core translation library
345
+ - **[@gringow/gringow-shadow](https://www.npmjs.com/package/@gringow/gringow-shadow)** - Web Component layer (this package depends on it)
346
+ - **[@gringow/gringow-vite](https://www.npmjs.com/package/@gringow/gringow-vite)** - Vite plugin for build-time extraction
347
+ - **[@gringow/cli](https://www.npmjs.com/package/@gringow/gringow-cli)** - CLI for translation management
348
+ - **[@gringow/gringow-nextjs](https://www.npmjs.com/package/@gringow/gringow-nextjs)** - Next.js plugin (experimental)
349
+
350
+ ## Resources
351
+
352
+ - [Documentation](https://gringow.dev)
353
+ - [GitHub Repository](https://github.com/rntgspr/gringow)
354
+ - [Example: React + Vite](https://github.com/rntgspr/gringow/tree/main/example-gringow-vite)
355
+
356
+ ## License
357
+
358
+ MIT © [Renato Gaspar](https://github.com/rntgspr)
359
+
360
+ ---
361
+
362
+ **Need Help?** Open an issue on [GitHub](https://github.com/rntgspr/gringow/issues)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gringow/gringow-react",
3
- "version": "0.0.8",
3
+ "version": "0.2.0",
4
4
  "description": "React bindings for Gringow AI-powered translation tool",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -35,8 +35,8 @@
35
35
  "@types/react": "^19.2.7",
36
36
  "react": "19.1.0",
37
37
  "react-dom": "19.1.0",
38
- "@gringow/gringow": "0.1.3",
39
- "@gringow/gringow-shadow": "0.0.3"
38
+ "@gringow/gringow": "0.2.0",
39
+ "@gringow/gringow-shadow": "0.2.0"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "rm -rf ./dist/* ./tsconfig.tsbuildinfo && tsup",