tempest-react-sdk 0.12.0 → 0.14.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.
@@ -243,6 +243,66 @@ export declare interface ApiError {
243
243
  body?: unknown;
244
244
  }
245
245
 
246
+ /**
247
+ * Mobile-first top app bar for PWAs — leading (back / brand) + title +
248
+ * trailing actions, sticky with safe-area padding out of the box.
249
+ *
250
+ * Consumers customise via tokens (`--tempest-*`) and slots; the SDK ships the
251
+ * layout, sticky/safe-area behaviour, and accessible back button so apps don't
252
+ * hand-roll one per screen. For a desktop three-slot nav use [[Navbar]].
253
+ *
254
+ * @example
255
+ * // Detail screen with back + a trailing action
256
+ * <AppBar
257
+ * title="Profile"
258
+ * showBack
259
+ * onBack={() => navigate(-1)}
260
+ * actions={<IconButton icon={<Settings />} onClick={openSettings} />}
261
+ * />
262
+ *
263
+ * @example
264
+ * // Home screen — brand left, centered title disabled
265
+ * <AppBar brand={<Logo />} actions={<UserMenu />} />
266
+ */
267
+ export declare function AppBar({ title, leading, showBack, onBack, backLabel, backIcon, brand, actions, centered, sticky, tone, bordered, safeArea, className, ...props }: AppBarProps): JSX.Element;
268
+
269
+ export declare interface AppBarProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
270
+ /** Page title — string or any node. Rendered as the bar's `<h1>`. */
271
+ title?: ReactNode;
272
+ /**
273
+ * Replace the whole left slot. When set, the auto back button and `brand`
274
+ * are ignored — you own the leading content.
275
+ */
276
+ leading?: ReactNode;
277
+ /** Show a back button in the left slot. Ignored when `leading` is set. */
278
+ showBack?: boolean;
279
+ /**
280
+ * Back-button handler. Defaults to `window.history.back()`. With a router,
281
+ * pass `onBack={() => navigate(-1)}`.
282
+ */
283
+ onBack?: () => void;
284
+ /** Accessible label for the back button. Default `"Go back"`. */
285
+ backLabel?: string;
286
+ /** Custom back icon. Default a left arrow. */
287
+ backIcon?: ReactNode;
288
+ /** Brand / logo node shown in the left slot (after the back button). */
289
+ brand?: ReactNode;
290
+ /** Right slot — action buttons / menu. One node or many. */
291
+ actions?: ReactNode;
292
+ /** Center the title (three-column grid). Default `false` (left-aligned). */
293
+ centered?: boolean;
294
+ /** Stick to the top of the scroll container. Default `true`. */
295
+ sticky?: boolean;
296
+ /** Visual tone. Default `"surface"`. */
297
+ tone?: AppBarTone;
298
+ /** Thin bottom border. Default `true`. */
299
+ bordered?: boolean;
300
+ /** Add `env(safe-area-inset-top)` padding (iOS notch / PWA). Default `true`. */
301
+ safeArea?: boolean;
302
+ }
303
+
304
+ export declare type AppBarTone = "surface" | "primary" | "transparent";
305
+
246
306
  /**
247
307
  * Compose the Tempest app-wide providers in one place: error boundary →
248
308
  * TanStack Query → theme → i18n. Query and theme are on by default; i18n and
@@ -2994,6 +3054,63 @@ export declare interface InstallBackgroundSyncOptions {
2994
3054
  maxRetentionMinutes?: number;
2995
3055
  }
2996
3056
 
3057
+ /**
3058
+ * Dismissible bottom banner that invites the user to install the PWA. Wired to
3059
+ * {@link useBeforeInstallPrompt}: it renders only when the browser captured an
3060
+ * install prompt and the app is not already running standalone — so on
3061
+ * platforms that never fire `beforeinstallprompt` (e.g. iOS Safari) it stays
3062
+ * hidden and you can surface manual instructions elsewhere.
3063
+ *
3064
+ * @example
3065
+ * <InstallBanner
3066
+ * title="Instale o FAMACHApp"
3067
+ * description="Acesso offline e atalho na tela inicial."
3068
+ * storageKey="famacha:install-dismissed"
3069
+ * />
3070
+ */
3071
+ export declare function InstallBanner({ title, description, installLabel, dismissLabel, icon, storageKey, onResult, className, }: InstallBannerProps): JSX.Element | null;
3072
+
3073
+ export declare interface InstallBannerProps {
3074
+ /** Headline. Default `"Instale o app"`. */
3075
+ title?: ReactNode;
3076
+ /** Supporting copy under the title. */
3077
+ description?: ReactNode;
3078
+ /** Install button label. Default `"Instalar"`. */
3079
+ installLabel?: string;
3080
+ /** Accessible label for the dismiss button. Default `"Dispensar"`. */
3081
+ dismissLabel?: string;
3082
+ /** Optional leading icon. */
3083
+ icon?: ReactNode;
3084
+ /**
3085
+ * `localStorage` key used to remember dismissal across reloads. Omit to
3086
+ * make dismissal last only for the current session (component state).
3087
+ */
3088
+ storageKey?: string;
3089
+ /** Called with the user's choice after the install prompt resolves. */
3090
+ onResult?: (outcome: InstallOutcome) => void;
3091
+ className?: string;
3092
+ }
3093
+
3094
+ /**
3095
+ * Button wired to the PWA install prompt ({@link useBeforeInstallPrompt}).
3096
+ * Renders nothing when the app can't be installed — no prompt captured yet,
3097
+ * already installed, or running standalone — so you can drop it anywhere
3098
+ * without guarding visibility yourself.
3099
+ *
3100
+ * Inherits every {@link Button} prop (`variant`, `size`, `leftIcon`, …).
3101
+ *
3102
+ * @example
3103
+ * <InstallButton variant="primary" leftIcon={<Download />} />
3104
+ */
3105
+ export declare function InstallButton({ label, onResult, ...props }: InstallButtonProps): JSX.Element | null;
3106
+
3107
+ export declare interface InstallButtonProps extends Omit<ButtonProps, "onClick" | "children"> {
3108
+ /** Button label. Default `"Instalar app"`. */
3109
+ label?: ReactNode;
3110
+ /** Called with the user's choice after the install prompt resolves. */
3111
+ onResult?: (outcome: InstallOutcome) => void;
3112
+ }
3113
+
2997
3114
  /**
2998
3115
  * Install a `notificationclick` handler that focuses an existing client when
2999
3116
  * possible and falls back to opening a new window.
@@ -3005,6 +3122,8 @@ export declare interface InstallNotificationClickHandlerOptions {
3005
3122
  resolveUrl?: (data: unknown) => string;
3006
3123
  }
3007
3124
 
3125
+ export declare type InstallOutcome = "accepted" | "dismissed" | "unsupported";
3126
+
3008
3127
  /**
3009
3128
  * Precache the app shell at `install` and serve it offline:
3010
3129
  * - reads `precache-manifest.json` (emitted by `tempestPwaManifest()`),
@@ -4933,13 +5052,33 @@ export declare interface SpacerProps extends HTMLAttributes<HTMLDivElement> {
4933
5052
  axis?: SpacerAxis;
4934
5053
  }
4935
5054
 
4936
- /** Loading spinner with preset sizes (xs..xl). Provide `label` for screen readers. */
4937
- export declare function Spinner({ size, className, label }: SpinnerProps): JSX.Element;
5055
+ /**
5056
+ * Loading spinner with preset sizes (xs..xl). Provide `label` for screen
5057
+ * readers, `caption` for a visible message, and `overlay` to center it inside a
5058
+ * full-area container (e.g. a Suspense / route fallback).
5059
+ *
5060
+ * @example
5061
+ * <Spinner />
5062
+ * <Spinner size="lg" caption="Carregando…" overlay />
5063
+ */
5064
+ export declare function Spinner({ size, className, label, caption, overlay, }: SpinnerProps): JSX.Element;
4938
5065
 
4939
5066
  export declare interface SpinnerProps {
4940
5067
  size?: SpinnerSize;
4941
5068
  className?: string;
5069
+ /** Accessible label announced by screen readers. */
4942
5070
  label?: string;
5071
+ /**
5072
+ * Visible caption rendered under the spinner. When set, the spinner and
5073
+ * caption are wrapped in a centered column.
5074
+ */
5075
+ caption?: ReactNode;
5076
+ /**
5077
+ * Center the spinner inside a full-area overlay (fills the nearest
5078
+ * positioned ancestor; pair with a relative container or a route fallback).
5079
+ * Implies the wrapped layout.
5080
+ */
5081
+ overlay?: boolean;
4943
5082
  }
4944
5083
 
4945
5084
  export declare type SpinnerSize = "xs" | "sm" | "md" | "lg" | "xl";
@@ -5351,7 +5490,7 @@ export declare type ThemeMode = "light" | "dark" | "system";
5351
5490
  * Pair with `themeInitScript()` in the HTML head to prevent the flash of
5352
5491
  * incorrect theme on first paint.
5353
5492
  */
5354
- export declare function ThemeProvider({ children, defaultTheme, storageKey, target, attribute, }: ThemeProviderProps): JSX.Element;
5493
+ export declare function ThemeProvider({ children, defaultTheme, storageKey, target, attribute, themeColor, }: ThemeProviderProps): JSX.Element;
5355
5494
 
5356
5495
  export declare interface ThemeProviderProps {
5357
5496
  children: ReactNode;
@@ -5360,12 +5499,30 @@ export declare interface ThemeProviderProps {
5360
5499
  /** localStorage key used to persist the preference. Pass `null` to disable persistence. Default: `"tempest-theme"`. */
5361
5500
  storageKey?: string | null;
5362
5501
  /**
5363
- * Element that receives the `data-tempest-theme` attribute. Defaults to
5502
+ * Element that receives the theme attribute(s). Defaults to
5364
5503
  * `document.documentElement`. Override when scoping the theme to a subtree.
5365
5504
  */
5366
5505
  target?: () => HTMLElement | null;
5367
- /** Attribute name written on the target. Default: `"data-tempest-theme"`. */
5368
- attribute?: string;
5506
+ /**
5507
+ * Attribute name(s) written on the target with the resolved theme
5508
+ * (`"light"` / `"dark"`). Default: `"data-tempest-theme"`.
5509
+ *
5510
+ * Pass an array to mirror the theme onto more than one attribute — handy
5511
+ * when the SDK components read `data-tempest-theme` but the host app's own
5512
+ * CSS keys off a different attribute (e.g. `["data-tempest-theme",
5513
+ * "data-theme"]`). Avoids a separate sync effect in the consumer.
5514
+ */
5515
+ attribute?: string | string[];
5516
+ /**
5517
+ * When set, keeps `<meta name="theme-color">` in sync with the resolved
5518
+ * theme — `content` becomes `themeColor.dark` in dark mode and
5519
+ * `themeColor.light` in light mode. The meta tag must already exist in the
5520
+ * document `<head>`. No-op when omitted.
5521
+ */
5522
+ themeColor?: {
5523
+ light: string;
5524
+ dark: string;
5525
+ };
5369
5526
  }
5370
5527
 
5371
5528
  /**
@@ -5766,6 +5923,12 @@ export declare interface UseBeforeInstallPromptResult {
5766
5923
  installable: boolean;
5767
5924
  /** True after the user accepts the install prompt. */
5768
5925
  installed: boolean;
5926
+ /**
5927
+ * True when the app is already running as an installed PWA (display-mode
5928
+ * `standalone`/`fullscreen`/`minimal-ui`, or iOS `navigator.standalone`).
5929
+ * Use it to hide install affordances for users who already installed.
5930
+ */
5931
+ isStandalone: boolean;
5769
5932
  /** Show the install prompt. Resolves with the user's choice. */
5770
5933
  prompt: () => Promise<"accepted" | "dismissed" | "unsupported">;
5771
5934
  }