gt-vue 0.0.0 → 0.1.0-iris.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # gt-vue
2
+
3
+ ## 0.1.0-iris.1
4
+
5
+ ### Patch Changes
6
+
7
+ - f2204b9: Translate statically authored custom-component default slots, preserve authored
8
+ Fragments, and align Branch and Plural wire values, rendering fallbacks, and
9
+ locale selection with React. Add React-compatible `context`, `id`, `maxChars`,
10
+ and `requiresReview` metadata to `<T>`, including compiler-facing `$` aliases.
11
+ - 5d8b78a: Migrate the package license from FSL-1.1-ALv2 to MIT.
12
+ - Updated dependencies [f2204b9]
13
+ - Updated dependencies [b05b470]
14
+ - Updated dependencies [5d8b78a]
15
+ - generaltranslation@9.1.3-iris.0
16
+ - gt-i18n@1.0.13-iris.0
17
+
18
+ ## 0.1.0-iris.0
19
+
20
+ ### Minor Changes
21
+
22
+ - 8d376e2: Add a lightweight Vue 3 runtime with catalog-backed string and rich-content
23
+ translation, cookie-backed reactive locale switching, child-only variables,
24
+ and typed value props for number, currency, and date formatting. Browser SPAs
25
+ restore the locale from a configurable cookie, while an explicit server locale
26
+ wins during SSR hydration.
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [8d376e2]
31
+ - gt-i18n@1.0.12-iris.0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright 2025 General Translation, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,191 @@
1
+ <p align="center">
2
+ <a href="https://generaltranslation.com/docs">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://generaltranslation.com/brand/gt-logo-dark.svg">
5
+ <img alt="General Translation" src="https://generaltranslation.com/brand/gt-logo-light.svg" width="100" height="100">
6
+ </picture>
7
+ </a>
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://generaltranslation.com/docs"><strong>Documentation</strong></a> · <a href="https://github.com/generaltranslation/gt/issues">Report Bug</a>
12
+ </p>
13
+
1
14
  # gt-vue
2
15
 
3
- Placeholder while we work on this! :)
16
+ A lightweight General Translation runtime for Vue 3.
17
+
18
+ > [!WARNING]
19
+ > `gt-vue` is currently unstable. Its API and behavior may change between
20
+ > releases while the package is under active development. Its 0.x releases
21
+ > are versioned independently from the stable React framework packages.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install gt-vue
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ Register one plugin instance with your Vue app. Translation files are loaded
32
+ once per locale and cached for the lifetime of that instance. The
33
+ `defaultLocale` uses source text as its catalog, so `loadTranslations` is never
34
+ called for that locale.
35
+
36
+ ```ts
37
+ // main.ts
38
+ import { createApp } from 'vue';
39
+ import { createGT } from 'gt-vue';
40
+ import App from './App.vue';
41
+
42
+ const loadTranslations = async (locale: string) => {
43
+ try {
44
+ return (await import(`./_gt/${locale}.json`)).default;
45
+ } catch {
46
+ return {};
47
+ }
48
+ };
49
+
50
+ createApp(App)
51
+ .use(createGT({ defaultLocale: 'en', loadTranslations }))
52
+ .mount('#app');
53
+ ```
54
+
55
+ Use `<T>` for rich content. `<Var>` values are provided as slot children, not
56
+ through `name` or `value` props.
57
+
58
+ ```vue
59
+ <script setup lang="ts">
60
+ import { T, Var, useGT, useLocale, useSetLocale } from 'gt-vue';
61
+
62
+ const name = 'Ada';
63
+ const gt = useGT();
64
+ const locale = useLocale();
65
+ const setLocale = useSetLocale();
66
+ </script>
67
+
68
+ <template>
69
+ <main>
70
+ <T context="welcome">
71
+ Hello,
72
+ <Var>{{ name }}</Var>
73
+ !
74
+ </T>
75
+ <p>{{ gt('A plain string', { $context: 'homepage' }) }}</p>
76
+ <button @click="setLocale(locale === 'en' ? 'fr' : 'en')">
77
+ {{ locale }}
78
+ </button>
79
+ </main>
80
+ </template>
81
+ ```
82
+
83
+ `useGT()` performs a synchronous catalog lookup. Its only option is
84
+ `$context`; braces are literal text and no ICU formatting or interpolation is
85
+ applied.
86
+
87
+ Statically authored default-slot content inside a custom component participates
88
+ in the surrounding translation. The component itself, its props, and its
89
+ listeners are preserved while the translated content replaces its default
90
+ slot:
91
+
92
+ ```vue
93
+ <T>
94
+ <DocsLink to="/docs">Read the documentation</DocsLink>
95
+ </T>
96
+ ```
97
+
98
+ Content created inside `DocsLink`'s implementation is not visible to the outer
99
+ `<T>`. Runtime values still belong in `<Var>`, and conditional alternatives
100
+ belong in `<Branch>` or `<Plural>`. Scoped and arbitrary named slots depend on
101
+ the child component's runtime behavior, so place `<T>` inside those slots or
102
+ enclose the dynamic component boundary in `<Var>`. Component tags inside `<T>`
103
+ must resolve at runtime; an unresolved component warning from Vue is a
104
+ configuration error and is not a supported translation source. Use direct
105
+ component tags inside an outer `<T>`: Vue's `<component :is>` and
106
+ `is="vue:..."` selector forms are intentionally rejected by extraction because
107
+ global runtime registration can change their component identity after build.
108
+
109
+ Vue built-ins with statically authored default content follow the same rule.
110
+ `<Suspense>` needs one additional distinction: its default content participates
111
+ in an outer `<T>`, while its fallback slot is preserved but excluded from that
112
+ translation. Prefer literal `<Suspense>` with a single default root. Immutable
113
+ aliases that the extractor can trace directly to `vue` are also supported.
114
+ Re-exported, globally registered, ref/computed-held, and other runtime-wrapped
115
+ Suspense aliases are not supported inside an outer `<T>`. Put `<T>` inside those
116
+ boundaries instead:
117
+
118
+ ```vue
119
+ <Suspense>
120
+ <T>Translatable content</T>
121
+ <template #fallback><T>Loading…</T></template>
122
+ </Suspense>
123
+ ```
124
+
125
+ ## Registered Messages
126
+
127
+ `msg()` marks a string at module scope and `useMessages()` resolves it inside
128
+ a component.
129
+
130
+ ```vue
131
+ <script setup lang="ts">
132
+ import { msg, useMessages } from 'gt-vue';
133
+
134
+ const title = msg('Settings', { $context: 'page title' });
135
+ const m = useMessages();
136
+ </script>
137
+
138
+ <template>
139
+ <h1>{{ m(title) }}</h1>
140
+ </template>
141
+ ```
142
+
143
+ ## Components
144
+
145
+ - `<T context="..." :max-chars="80" requires-review>` translates rich slot
146
+ content and supplies translation metadata. The deprecated `id` prop is
147
+ accepted for React API compatibility but does not replace the content-based
148
+ catalog hash.
149
+ - `<Var>` preserves a dynamic slot value inside `<T>`.
150
+ - `<Num>`, `<DateTime>`, and `<Currency>` require typed runtime values through
151
+ `:value`; formatter slot children are not supported.
152
+ - `<Plural :n="count">` selects named slots such as `#one` and `#other`.
153
+ - `<Branch :branch="key">` selects an arbitrary named slot.
154
+
155
+ Use the required `value` prop for every formatting value.
156
+
157
+ ```vue
158
+ <Num :value="count" />
159
+ <Currency :value="price" currency="USD" />
160
+ <DateTime :value="createdAt" :options="{ dateStyle: 'medium' }" />
161
+ ```
162
+
163
+ When the active locale is the configured default, formatting ignores explicit
164
+ `locales` and uses only that default locale. Otherwise, an explicit `locales`
165
+ list on a standalone formatter is tried first, followed by the active locale
166
+ and then the default locale. Inside `<T>`, the rich translation pipeline owns
167
+ formatting locales: source fallbacks use the default locale, while translated
168
+ content uses the active locale followed by the default.
169
+
170
+ In a browser, gt-vue persists the active locale in the
171
+ `generaltranslation.locale` path-wide session cookie. When `locale` is omitted
172
+ from `createGT()`, that cookie wins over `defaultLocale`. Use
173
+ `localeCookieName` to share a different cookie with your routing or server
174
+ integration.
175
+
176
+ `setLocale()` loads a missing catalog before writing the cookie and rerendering
177
+ consumers. A failed or superseded request leaves both the cookie and rendered
178
+ locale unchanged. Direct changes to `document.cookie` are reflected by
179
+ `plugin.getLocale()` and the next Vue render, but browsers do not emit cookie
180
+ change events, so they do not schedule a render by themselves. Use gt-vue's
181
+ setter for reactive locale changes.
182
+
183
+ For SSR, resolve the request locale on the server and pass it as
184
+ `createGT({ locale })`. An explicit locale wins over a stale browser cookie,
185
+ which keeps hydration consistent and synchronizes the client cookie. Call and
186
+ await `plugin.loadTranslations(locale)` or `plugin.setLocale(locale)` before
187
+ server rendering. Create and preload the client plugin with the same locale
188
+ before hydrating; starting hydration before its asynchronous catalog is ready
189
+ can produce source text and a hydration mismatch. Create a fresh `createGT()`
190
+ instance for every server request so locale and catalog state remain
191
+ request-scoped.