gt-vue 0.0.0 → 0.1.0-iris.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # gt-vue
2
+
3
+ ## 0.1.0-iris.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8d376e2: Add a lightweight Vue 3 runtime with catalog-backed string and rich-content
8
+ translation, cookie-backed reactive locale switching, child-only variables,
9
+ and typed value props for number, currency, and date formatting. Browser SPAs
10
+ restore the locale from a configurable cookie, while an explicit server locale
11
+ wins during SSR hydration.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [8d376e2]
16
+ - gt-i18n@1.0.12-iris.0
package/LICENSE.md ADDED
@@ -0,0 +1,105 @@
1
+ # Functional Source License, Version 1.1, ALv2 Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-ALv2
6
+
7
+ ## Notice
8
+
9
+ Copyright 2025 General Translation, Inc.
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the Apache License, Version 2.0 that is effective on the second anniversary of
91
+ the date we make the Software available. On or after that date, you may use the
92
+ Software under the Apache License, Version 2.0, in which case the following
93
+ will apply:
94
+
95
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
96
+ this file except in compliance with the License.
97
+
98
+ You may obtain a copy of the License at
99
+
100
+ http://www.apache.org/licenses/LICENSE-2.0
101
+
102
+ Unless required by applicable law or agreed to in writing, software distributed
103
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
104
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
105
+ specific language governing permissions and limitations under the License.
package/README.md CHANGED
@@ -1,3 +1,175 @@
1
+ <p align="center">
2
+ <a href="https://generaltranslation.com/docs/vue">
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/vue"><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
+ Arbitrary component slots are opaque when placed inside `<T>`. Vue does not
88
+ expose a reliable way to inspect a component slot without executing user code,
89
+ so the component and its real runtime slots are preserved, but their content is
90
+ not part of the surrounding rich translation. To translate slot content, place
91
+ `<T>` inside the slot and wrap runtime values in `<Var>`. Native elements and
92
+ the slots owned by GT's `<Branch>` and `<Plural>` components remain part of the
93
+ surrounding translation. Component tags inside `<T>` must resolve at runtime;
94
+ an unresolved component warning from Vue is a configuration error and is not a
95
+ supported translation source.
96
+
97
+ Vue `<Suspense>` is the one built-in whose default content participates in an
98
+ outer `<T>`. Prefer literal `<Suspense>` and use a single default root. Immutable
99
+ aliases that the extractor can trace directly to `vue` are also supported; the
100
+ fallback slot is preserved but excluded from the outer translation. Re-exported,
101
+ globally registered, ref/computed-held, and other runtime-wrapped Suspense
102
+ aliases are not supported inside an outer `<T>`. Put `<T>` inside those
103
+ boundaries instead:
104
+
105
+ ```vue
106
+ <Suspense>
107
+ <T>Translatable content</T>
108
+ <template #fallback><T>Loading…</T></template>
109
+ </Suspense>
110
+ ```
111
+
112
+ ## Registered Messages
113
+
114
+ `msg()` marks a string at module scope and `useMessages()` resolves it inside
115
+ a component.
116
+
117
+ ```vue
118
+ <script setup lang="ts">
119
+ import { msg, useMessages } from 'gt-vue';
120
+
121
+ const title = msg('Settings', { $context: 'page title' });
122
+ const m = useMessages();
123
+ </script>
124
+
125
+ <template>
126
+ <h1>{{ m(title) }}</h1>
127
+ </template>
128
+ ```
129
+
130
+ ## Components
131
+
132
+ - `<T context="...">` translates rich slot content.
133
+ - `<Var>` preserves a dynamic slot value inside `<T>`.
134
+ - `<Num>`, `<DateTime>`, and `<Currency>` require typed runtime values through
135
+ `:value`; formatter slot children are not supported.
136
+ - `<Plural :n="count">` selects named slots such as `#one` and `#other`.
137
+ - `<Branch :branch="key">` selects an arbitrary named slot.
138
+
139
+ Use the required `value` prop for every formatting value.
140
+
141
+ ```vue
142
+ <Num :value="count" />
143
+ <Currency :value="price" currency="USD" />
144
+ <DateTime :value="createdAt" :options="{ dateStyle: 'medium' }" />
145
+ ```
146
+
147
+ When the active locale is the configured default, formatting ignores explicit
148
+ `locales` and uses only that default locale. Otherwise, an explicit `locales`
149
+ list on a standalone formatter is tried first, followed by the active locale
150
+ and then the default locale. Inside `<T>`, the rich translation pipeline owns
151
+ formatting locales: source fallbacks use the default locale, while translated
152
+ content uses the active locale followed by the default.
153
+
154
+ In a browser, gt-vue persists the active locale in the
155
+ `generaltranslation.locale` path-wide session cookie. When `locale` is omitted
156
+ from `createGT()`, that cookie wins over `defaultLocale`. Use
157
+ `localeCookieName` to share a different cookie with your routing or server
158
+ integration.
159
+
160
+ `setLocale()` loads a missing catalog before writing the cookie and rerendering
161
+ consumers. A failed or superseded request leaves both the cookie and rendered
162
+ locale unchanged. Direct changes to `document.cookie` are reflected by
163
+ `plugin.getLocale()` and the next Vue render, but browsers do not emit cookie
164
+ change events, so they do not schedule a render by themselves. Use gt-vue's
165
+ setter for reactive locale changes.
166
+
167
+ For SSR, resolve the request locale on the server and pass it as
168
+ `createGT({ locale })`. An explicit locale wins over a stale browser cookie,
169
+ which keeps hydration consistent and synchronizes the client cookie. Call and
170
+ await `plugin.loadTranslations(locale)` or `plugin.setLocale(locale)` before
171
+ server rendering. Create and preload the client plugin with the same locale
172
+ before hydrating; starting hydration before its asynchronous catalog is ready
173
+ can produce source text and a hydration mismatch. Create a fresh `createGT()`
174
+ instance for every server request so locale and catalog state remain
175
+ request-scoped.