@groveback/ui 0.4.0 → 0.5.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/SignIn.d.ts CHANGED
@@ -10,6 +10,7 @@
10
10
  * through the same endpoints, and the same rate limits, as a hand-written form would.
11
11
  */
12
12
  import type { ReactNode } from 'react';
13
+ import type { UiMessages } from './messages';
13
14
  import type { Doc } from './types';
14
15
  /**
15
16
  * The slice of the SDK's `client.auth` the gate uses. `login` may resolve with
@@ -32,6 +33,20 @@ export interface SignInProps {
32
33
  allowRegister?: boolean | undefined;
33
34
  /** Called with the user after a successful sign-in or registration. */
34
35
  onSignedIn?: ((user: Doc) => void) | undefined;
36
+ /**
37
+ * Language for the form's own words. Optional, and normally unnecessary: under
38
+ * `<GroveRoutes>` the gate reads the shell's locale like every other primitive.
39
+ *
40
+ * It exists for the mount that wraps the WHOLE router — `<SignIn><GroveRoutes /></SignIn>`,
41
+ * the way an app puts every page behind a session. That places the form above the provider
42
+ * carrying the locale, so a Spanish app came up with an English sign-in screen in front of
43
+ * translated pages. Absent, the gate falls back to the provider when there is one and then
44
+ * to the viewer's own languages, so that mount is now translated with no prop at all; pass
45
+ * one to drive it from the app's own switcher.
46
+ */
47
+ locale?: string | undefined;
48
+ /** Overrides for the form's words, merged over the shipped catalogue (see `messages.ts`). */
49
+ messages?: Partial<UiMessages> | undefined;
35
50
  /** What a signed-in viewer sees — normally the app's routes. */
36
51
  children: ReactNode;
37
52
  }
package/dist/index.d.ts CHANGED
@@ -16,8 +16,8 @@ import { RelationSelect } from './RelationSelect';
16
16
  import { GroveRoutes, RouteIndex, matchRoute, resolveRoute } from './routes';
17
17
  import { SignIn } from './SignIn';
18
18
  import { uiMessagesFor } from './messages';
19
- import { GroveUiProvider, detectLocale, formatValue, resolveHref, useAction, useGroveUi, useMessages, usePageTitle, useUiMessages, useUiText } from './runtime';
20
- export { Button, DataTable, Detail, Divider, Form, Grid, GroveRoutes, GroveUiProvider, Header, Heading, MarkdownField, renderMarkdown, RelationSelect, RouteIndex, SignIn, Stack, Text, detectLocale, formatValue, matchRoute, resolveHref, resolveRoute, useAction, useGroveUi, useMessages, usePageTitle, uiMessagesFor, useUiMessages, useUiText, };
19
+ import { GroveUiProvider, detectLocale, formatValue, resolveHref, useAction, useGroveUi, useMessages, usePageTitle, useStandaloneUiText, useUiMessages, useUiText } from './runtime';
20
+ export { Button, DataTable, Detail, Divider, Form, Grid, GroveRoutes, GroveUiProvider, Header, Heading, MarkdownField, renderMarkdown, RelationSelect, RouteIndex, SignIn, Stack, Text, detectLocale, formatValue, matchRoute, resolveHref, resolveRoute, useAction, useGroveUi, useMessages, usePageTitle, useStandaloneUiText, uiMessagesFor, useUiMessages, useUiText, };
21
21
  export type { RelationSelectProps } from './RelationSelect';
22
22
  export type { GroveUiContext } from './runtime';
23
23
  export type { UiMessageKey, UiMessages } from './messages';
package/dist/index.js CHANGED
@@ -138,6 +138,12 @@ function useUiMessages() {
138
138
  const ctx = useGroveUi();
139
139
  return useMemo(() => ({ ...uiMessagesFor(ctx.locale), ...ctx.messages }), [ctx]);
140
140
  }
141
+ function useStandaloneUiText(locale, overrides) {
142
+ const ctx = useGroveUi();
143
+ const active = locale ?? ctx.locale ?? detectLocale(Object.keys(UI_LOCALES));
144
+ const messages = { ...ctx.messages, ...overrides };
145
+ return useCallback((key) => messages[key] ?? uiMessagesFor(active)[key], [active, ctx.messages, overrides]);
146
+ }
141
147
  function resolveHref(href, doc) {
142
148
  if (!doc)
143
149
  return href;
@@ -1191,8 +1197,16 @@ function RouteIndex({ routes }) {
1191
1197
  import { useCallback as useCallback4, useRef as useRef3, useState as useState5 } from "react";
1192
1198
  import { jsx as jsx6, jsxs as jsxs5, Fragment as Fragment2 } from "react/jsx-runtime";
1193
1199
  function SignIn(props) {
1194
- const { auth, title, allowRegister = typeof auth.register === "function", onSignedIn, children } = props;
1195
- const t = useUiText();
1200
+ const {
1201
+ auth,
1202
+ title,
1203
+ allowRegister = typeof auth.register === "function",
1204
+ onSignedIn,
1205
+ locale,
1206
+ messages,
1207
+ children
1208
+ } = props;
1209
+ const t = useStandaloneUiText(locale, messages);
1196
1210
  const [signedIn, setSignedIn] = useState5(() => auth.getTokens() !== null);
1197
1211
  const [mode, setMode] = useState5("login");
1198
1212
  const [email, setEmail] = useState5("");
@@ -1382,6 +1396,7 @@ export {
1382
1396
  useGroveUi,
1383
1397
  useMessages,
1384
1398
  usePageTitle,
1399
+ useStandaloneUiText,
1385
1400
  useUiMessages,
1386
1401
  useUiText
1387
1402
  };
package/dist/runtime.d.ts CHANGED
@@ -51,6 +51,20 @@ export declare function uiText(ctx: GroveUiContext, key: UiMessageKey): string;
51
51
  export declare function useUiText(): (key: UiMessageKey) => string;
52
52
  /** The chrome catalogue in force — for the few places that need several keys at once. */
53
53
  export declare function useUiMessages(): UiMessages;
54
+ /**
55
+ * The chrome translator for a component that may render OUTSIDE the provider.
56
+ *
57
+ * `SignIn` is the case this exists for: the generated app can mount it around the whole
58
+ * router (`<SignIn><GroveRoutes /></SignIn>`), which puts the form ABOVE the provider that
59
+ * carries the locale — so the sign-in screen of a Spanish app came up in English while every
60
+ * page behind it was translated. Rather than make the app thread a locale through by hand,
61
+ * such a component resolves one itself: an explicit prop, else the provider when there is
62
+ * one, else the viewer's own languages.
63
+ *
64
+ * `available` is the set to match the viewer against — the locales the catalogue ships, since
65
+ * a component outside the provider has no document to ask.
66
+ */
67
+ export declare function useStandaloneUiText(locale: string | undefined, overrides: Partial<UiMessages> | undefined): (key: UiMessageKey) => string;
54
68
  /** Substitute `:param` segments in an href with a document's values. */
55
69
  export declare function resolveHref(href: string, doc?: Doc): string;
56
70
  export interface DispatchOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groveback/ui",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "React primitives for Groveback Studio screens — tables, forms, detail views and relation pickers that read through the Groveback SDK, so every query passes the policy engine.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",