@nebulahome/package-sdk 1.0.0 → 1.1.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/dist/ui.d.ts CHANGED
@@ -128,6 +128,27 @@ type Locale = {
128
128
  readonly locale: string;
129
129
  readonly timeZone: string;
130
130
  };
131
+ /** A plural's English: the form for one, and the form for any other number. */
132
+ type PluralEnglish = {
133
+ readonly one: string;
134
+ readonly other: string;
135
+ };
136
+ /** What fills a string's `{{placeholders}}`; `count` also picks a plural's form. */
137
+ type TranslationValues = Readonly<Record<string, string | number>>;
138
+ /**
139
+ * Says one of the package's strings in the viewer's language.
140
+ *
141
+ * The key is looked up in the package's catalogue for that language (`locales/it.json`); when it
142
+ * is not there, the English given here is said instead. A plural takes its English as
143
+ * `{ one, other }` and the number as `count`: each language's catalogue holds the forms it needs.
144
+ */
145
+ type Translate = (key: string, english: string | PluralEnglish, values?: TranslationValues) => string;
146
+ /** The package's strings, in the viewer's language. */
147
+ type Translation = {
148
+ readonly t: Translate;
149
+ /** The language they are said in, `it`: the viewer's, whether or not the package has it. */
150
+ readonly locale: string;
151
+ };
131
152
  /** Which theme the interface draws in. */
132
153
  type Theme = {
133
154
  readonly scheme: 'light' | 'dark';
@@ -185,6 +206,8 @@ type UiHost = {
185
206
  readonly usePackageSettings: <TSettings extends SettingsDefinition | undefined = undefined>(settings?: TSettings) => PackageSettings<TSettings>;
186
207
  readonly useViewer: () => Viewer;
187
208
  readonly useLocale: () => Locale;
209
+ /** Since 1.1. */
210
+ readonly useTranslation: () => Translation;
188
211
  readonly useTheme: () => Theme;
189
212
  readonly usePortalContainer: () => HTMLElement | null;
190
213
  readonly usePackageRoute: () => PackageRoute;
@@ -272,6 +295,17 @@ export declare function useViewer(): Viewer;
272
295
  * @returns Them, for `Intl`.
273
296
  */
274
297
  export declare function useLocale(): Locale;
298
+ /**
299
+ * The package's strings in the viewer's language, from the catalogues in its `locales` folder
300
+ * (PACKAGES_DOCS.md 6.5).
301
+ *
302
+ * `t('clients.title', 'Clients')` says the key from the viewer's catalogue, and its English when
303
+ * the catalogue lacks it; outside an interface that lends this - a component's unit test - every
304
+ * string is its English.
305
+ *
306
+ * @returns `t`, and the language it speaks.
307
+ */
308
+ export declare function useTranslation(): Translation;
275
309
  /**
276
310
  * The theme the interface draws in, for what draws its own colours: a canvas, a chart.
277
311
  *
@@ -317,4 +351,4 @@ export declare function PackageLink(props: PackageLinkProps): ReactElement;
317
351
  */
318
352
  export declare function PlatformLink(props: PlatformLinkProps): ReactElement;
319
353
  //#endregion
320
- export type { CardProps, CustomEntityState, EntitiesFilter, EntityView, EntityViewProps, Locale, Mutation, MutationOptions, PackageCall, PackageInfo, PackageLinkProps, PackageNavigate, PackageRoute, PackageSettings, PageProps, PlatformLinkProps, PlatformNavigate, PlatformTarget, RpcOptions, RpcState, SendCommand, SettingsPatch, Theme, UiHost, Viewer, VisibleSettings };
354
+ export type { CardProps, CustomEntityState, EntitiesFilter, EntityView, EntityViewProps, Locale, Mutation, MutationOptions, PackageCall, PackageInfo, PackageLinkProps, PackageNavigate, PackageRoute, PackageSettings, PageProps, PlatformLinkProps, PlatformNavigate, PlatformTarget, PluralEnglish, RpcOptions, RpcState, SendCommand, SettingsPatch, Theme, Translate, Translation, TranslationValues, UiHost, Viewer, VisibleSettings };
package/dist/ui.js CHANGED
@@ -1,5 +1,45 @@
1
- import { n as UI_MODULE, r as hostMember } from "./chunks/host.js";
1
+ import { i as lentMember, n as UI_MODULE, r as hostMember } from "./chunks/host.js";
2
2
  import { createElement } from "react";
3
+ //#region src/ui/english.ts
4
+ /** A `{{placeholder}}`, as i18next writes it. */
5
+ const PLACEHOLDER = /\{\{\s*(\w+)\s*\}\}/g;
6
+ /**
7
+ * Fills a string's placeholders.
8
+ *
9
+ * @param text - The string.
10
+ * @param values - What fills them; a placeholder with no value is left as written.
11
+ * @returns The string, filled.
12
+ */
13
+ function interpolate(text, values) {
14
+ return text.replaceAll(PLACEHOLDER, (whole, name) => {
15
+ const value = values?.[name];
16
+ return value === void 0 ? whole : String(value);
17
+ });
18
+ }
19
+ /**
20
+ * Says a string's English, its plural form chosen by `count`.
21
+ *
22
+ * @param english - The English, or a plural's two forms.
23
+ * @param values - What fills it.
24
+ * @returns The English, filled.
25
+ */
26
+ function englishOf(english, values) {
27
+ return interpolate(typeof english === "string" ? english : values?.["count"] === 1 ? english.one : english.other, values);
28
+ }
29
+ /** The package's strings in English. */
30
+ const ENGLISH = {
31
+ /**
32
+ * Says a string's English.
33
+ *
34
+ * @param key - Its key, unused: there is no catalogue here.
35
+ * @param english - Its English.
36
+ * @param values - What fills it.
37
+ * @returns The English, filled.
38
+ */
39
+ t: (key, english, values) => englishOf(english, values),
40
+ locale: "en"
41
+ };
42
+ //#endregion
3
43
  //#region src/ui/index.ts
4
44
  /**
5
45
  * `@nebulahome/package-sdk/ui`: what a package's page, cards and entity views are written with
@@ -119,6 +159,20 @@ function useLocale() {
119
159
  return ui("useLocale", "1.0")();
120
160
  }
121
161
  /**
162
+ * The package's strings in the viewer's language, from the catalogues in its `locales` folder
163
+ * (PACKAGES_DOCS.md 6.5).
164
+ *
165
+ * `t('clients.title', 'Clients')` says the key from the viewer's catalogue, and its English when
166
+ * the catalogue lacks it; outside an interface that lends this - a component's unit test - every
167
+ * string is its English.
168
+ *
169
+ * @returns `t`, and the language it speaks.
170
+ */
171
+ function useTranslation() {
172
+ const lent = lentMember(UI_MODULE, "useTranslation");
173
+ return lent === void 0 ? ENGLISH : lent();
174
+ }
175
+ /**
122
176
  * The theme the interface draws in, for what draws its own colours: a canvas, a chart.
123
177
  *
124
178
  * @returns Light or dark.
@@ -177,4 +231,4 @@ function PlatformLink(props) {
177
231
  return createElement(ui("PlatformLink", "1.0"), props);
178
232
  }
179
233
  //#endregion
180
- export { PackageLink, PlatformLink, useCommand, useCustomEntity, useEntities, useEntity, useLocale, usePackage, usePackageCall, usePackageMutation, usePackageNavigate, usePackageRoute, usePackageRpc, usePackageSettings, usePlatformNavigate, usePortalContainer, useTheme, useViewer };
234
+ export { PackageLink, PlatformLink, useCommand, useCustomEntity, useEntities, useEntity, useLocale, usePackage, usePackageCall, usePackageMutation, usePackageNavigate, usePackageRoute, usePackageRpc, usePackageSettings, usePlatformNavigate, usePortalContainer, useTheme, useTranslation, useViewer };
package/dist/vite.d.ts CHANGED
@@ -52,8 +52,8 @@ type CheckedPackage = {
52
52
  readonly generated: GeneratedPackage;
53
53
  };
54
54
  /**
55
- * Checks a package without building it: its declaration against the platform's schemas, and the
56
- * files it names.
55
+ * Checks a package without building it: its declaration against the platform's schemas, the
56
+ * files it names, and its translation catalogues.
57
57
  *
58
58
  * @param options - Where the package is.
59
59
  * @returns The package, checked.
package/dist/vite.js CHANGED
@@ -1,2 +1,3 @@
1
- import { n as checkPackage, r as nebula, t as buildPackage, w as PackageConfigError } from "./chunks/node-build.js";
1
+ import { n as checkPackage, r as nebula, t as buildPackage } from "./chunks/node-build.js";
2
+ import { t as PackageConfigError } from "./chunks/node-problems.js";
2
3
  export { PackageConfigError, buildPackage, checkPackage, nebula };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebulahome/package-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Write a NebulaHome package: declare it, build it, and run it on the platform.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -96,10 +96,10 @@
96
96
  "vitest": "^4.1.11",
97
97
  "yaml": "^2.9.0",
98
98
  "zod": "^4.5.4",
99
- "@nebulahome/tsconfig": "0.0.0",
100
99
  "@nebulahome/contracts": "0.0.0",
101
- "@nebulahome/eslint-config": "0.0.0",
102
- "@nebulahome/ui": "0.0.0"
100
+ "@nebulahome/tsconfig": "0.0.0",
101
+ "@nebulahome/ui": "0.0.0",
102
+ "@nebulahome/eslint-config": "0.0.0"
103
103
  },
104
104
  "scripts": {
105
105
  "build": "tsdown && node scripts/build-styles.js",