@abyss-project/commons-front-core 13.3.0 → 14.0.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.
Files changed (94) hide show
  1. package/catalog/captures-plan.ts +4 -1
  2. package/catalog/catalog-entries.ts +6 -1
  3. package/catalog/expected-error.ts +6 -0
  4. package/catalog/pages/CookieConsent.tsx +38 -0
  5. package/catalog/pages/ErrorBoundary.tsx +22 -0
  6. package/catalog/pages/PasswordField.tsx +62 -0
  7. package/catalog/pages/Toast.tsx +17 -6
  8. package/catalog/pages/index.ts +6 -0
  9. package/catalog/specs/captures.spec.ts +10 -0
  10. package/catalog/specs/catalog-page.ts +6 -1
  11. package/catalog/specs/write-capture-index.ts +1 -0
  12. package/dist/{AbyssCloud-D_AbU9k7.js → AbyssCloud-B3rMelRi.js} +636 -712
  13. package/dist/CookieConsentSettings-DyJGEnVA.js +505 -0
  14. package/dist/{use-rich-intl.hook-BETUyCkW.js → Surface-B_J_I_1i.js} +700 -147
  15. package/dist/Tabs-_TzugjHZ.js +1941 -0
  16. package/dist/auth/components/AuthHeroLayout/auth-hero-gradient.d.ts +18 -0
  17. package/dist/auth/components/shared/AuthLoadingScreen.component.d.ts +5 -0
  18. package/dist/auth/components/shared/use-async-resource.hook.d.ts +4 -1
  19. package/dist/auth/components/shared/use-async-resource.hook.spec.d.ts +1 -0
  20. package/dist/components/business/CookieConsent/AbyssCookieConsentProvider.spec.d.ts +1 -0
  21. package/dist/components/business/CookieConsent/CookieConsent.spec.d.ts +1 -0
  22. package/dist/{legacy/components/CookieConsent/CookieConsentBanner.component.d.ts → components/business/CookieConsent/CookieConsentBanner.d.ts} +1 -2
  23. package/dist/components/business/CookieConsent/CookieConsentSettings.d.ts +1 -0
  24. package/dist/{legacy/components → components/business}/CookieConsent/index.d.ts +2 -2
  25. package/dist/components/business/index.d.ts +3 -0
  26. package/dist/components/inputs/FormField/FormField.d.ts +5 -1
  27. package/dist/components/inputs/PasswordField/PasswordField.d.ts +40 -0
  28. package/dist/components/inputs/PasswordField/PasswordField.spec.d.ts +1 -0
  29. package/dist/components/inputs/index.d.ts +1 -0
  30. package/dist/components/layers/Toast/Toast.d.ts +3 -18
  31. package/dist/components/layers/Toast/toast-clearance.d.ts +6 -0
  32. package/dist/components/layers/Toast/toast-store.d.ts +76 -0
  33. package/dist/components/states/ErrorBoundary/ErrorBoundary.d.ts +17 -0
  34. package/dist/components/states/ErrorBoundary/ErrorBoundary.spec.d.ts +1 -0
  35. package/dist/components/states/PageState/PageState.d.ts +3 -1
  36. package/dist/components/states/index.d.ts +1 -0
  37. package/dist/cookie-consent.d.ts +1 -1
  38. package/dist/cookie-consent.js +14 -15
  39. package/dist/demo/DemoBanner/DemoBanner.d.ts +16 -0
  40. package/dist/demo/DemoBanner/DemoBanner.spec.d.ts +1 -0
  41. package/dist/demo/DemoBanner/index.d.ts +1 -0
  42. package/dist/demo/demo-blocked.interceptor.d.ts +7 -0
  43. package/dist/demo/demo.en.d.ts +17 -0
  44. package/dist/demo/demo.fr.d.ts +17 -0
  45. package/dist/demo/index.d.ts +3 -0
  46. package/dist/demo/tests/demo-blocked.interceptor.spec.d.ts +1 -0
  47. package/dist/demo/use-demo-account.hook.d.ts +19 -0
  48. package/dist/design-theme-D5L0JNbX.js +26599 -0
  49. package/dist/{editors-CUsZNFfw.js → editors-C6Rocm6M.js} +83 -83
  50. package/dist/editors.js +1 -1
  51. package/dist/hooks/use-rich-intl.hook.d.ts +80 -0
  52. package/dist/{index-BQ4GXlMJ.js → index-5AavH8Oo.js} +1 -1
  53. package/dist/{index-Bn4gTAno.js → index-B58_3EoW.js} +2 -2
  54. package/dist/{index-DuMzZrqc.js → index-BElPTqLa.js} +2 -2
  55. package/dist/{index-D1ro2oTw.js → index-BI4ooqu1.js} +2 -2
  56. package/dist/{index-TB7ekLl-.js → index-BYDMmzla.js} +2 -2
  57. package/dist/{index-CM0x-TnE.js → index-C1GCQ2Ke.js} +2 -2
  58. package/dist/{index-DEBTvCWD.js → index-C1I7MW-q.js} +3 -3
  59. package/dist/{index-pnfk6VZ7.js → index-CDI4_t7D.js} +4 -4
  60. package/dist/{index-Lyt4_W7a.js → index-CDWJlhuZ.js} +2 -2
  61. package/dist/{index-C7a2XXcz.js → index-CKJMsjnV.js} +4 -4
  62. package/dist/{index-CDpC4_po.js → index-Cskjr11h.js} +2 -2
  63. package/dist/{index-DErJ9c2q.js → index-CuYK_i3Q.js} +2 -2
  64. package/dist/{index-GTkZik4b.js → index-Cwgj3j50.js} +3 -3
  65. package/dist/{index-CjV5ui_B.js → index-Czhx2OUB.js} +2 -2
  66. package/dist/{index-CiDg4J7c.js → index-DGoR-pBV.js} +4 -4
  67. package/dist/{index-YzYX-H93.js → index-DjAZPCEQ.js} +3 -3
  68. package/dist/{index-Ba41aBBN.js → index-Dutd4cJm.js} +2 -2
  69. package/dist/{index-DobX4g2g.js → index-Dym_r-do.js} +2 -2
  70. package/dist/{index-BhFOCfCj.js → index-TshVV9T4.js} +2 -2
  71. package/dist/{index-BzoBMWdL.js → index-UjGNADrL.js} +3 -3
  72. package/dist/{index-CYUixRIB.js → index-u-EAOYOb.js} +2 -2
  73. package/dist/index.d.ts +1 -0
  74. package/dist/index.js +5483 -4750
  75. package/dist/legacy/components/Spotlight/ProjectLinkSelector/index.d.ts +1 -4
  76. package/dist/legacy/components/Support/AbyssServiceSelect.component.d.ts +1 -1
  77. package/dist/legacy/components/index.d.ts +1 -1
  78. package/dist/legacy.js +9626 -8129
  79. package/dist/translations/en.d.ts +39 -0
  80. package/dist/translations/fr.d.ts +39 -0
  81. package/dist/utils/index.d.ts +2 -0
  82. package/dist/utils/project-link-mode.d.ts +4 -0
  83. package/dist/utils/project-link-wording.utils.d.ts +1 -1
  84. package/dist/utils/service-config.d.ts +8 -0
  85. package/dist/utils/service-config.spec.d.ts +1 -0
  86. package/package.json +3 -3
  87. package/vite.config.ts +1 -1
  88. package/dist/AbyssCookieConsentProvider-Ds99df0E.js +0 -4562
  89. package/dist/CookieConsentSettings.component-DoWLHqw5.js +0 -78
  90. package/dist/Tabs-C1qcQ2i5.js +0 -2335
  91. package/dist/design-theme-CYGZ6mAh.js +0 -23975
  92. package/dist/legacy/components/CookieConsent/CookieConsentSettings.component.d.ts +0 -2
  93. /package/dist/{legacy/components/CookieConsent/AbyssCookieConsentProvider.spec.d.ts → auth/components/SecuritySettings/sections/SessionsSection.component.spec.d.ts} +0 -0
  94. /package/dist/{legacy/components → components/business}/CookieConsent/AbyssCookieConsentProvider.d.ts +0 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The ends of the hero's brand gradient. Those of the light theme in both modes: the dark theme's
3
+ * (a pale blue) are made for a surface that is lit from below, and put the hero's white text under
4
+ * 4.5:1 (CA12). The hero is a brand surface that carries white text, so it keeps one dark enough
5
+ * background whatever the mode.
6
+ */
7
+ export declare const HERO_GRADIENT_FROM: string;
8
+ export declare const HERO_GRADIENT_TO: string;
9
+ /** The shade under the text: transparent up to this share of the hero's height, then growing. */
10
+ export declare const HERO_SHADE_START = 0.15;
11
+ /** Opacity of the black shade at the bottom edge of the hero. */
12
+ export declare const HERO_SHADE_ALPHA = 0.5;
13
+ /**
14
+ * The highest point of the hero, as a share of its height, where its text can start (the compact
15
+ * row, its name centred next to the tile): from there down, the shade is what the contrast is
16
+ * measured with.
17
+ */
18
+ export declare const HERO_TEXT_TOP = 0.5;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The full-frame loading state shown while the session is restored: the `PageState` loading status
3
+ * (a named, busy `status`) with a centered progress indicator as its skeleton.
4
+ */
5
+ export declare const AuthLoadingScreen: () => import("react/jsx-runtime").JSX.Element;
@@ -13,6 +13,9 @@ export interface AsyncResource<T> {
13
13
  }
14
14
  /**
15
15
  * Loads `load()` on mount and on every `reload()`. An answer that a later load overtook is
16
- * dropped, so a slow first answer never overwrites a fresh one.
16
+ * dropped, so a slow first answer never overwrites a fresh one. One load per version: React's
17
+ * development double-run of effects reuses the request in flight instead of sending a second one,
18
+ * which matters when the call is not idempotent (the authenticator setup draws a new secret each
19
+ * time, and the one shown must be the one the server kept).
17
20
  */
18
21
  export declare const useAsyncResource: <T>(load: () => Promise<T>) => AsyncResource<T>;
@@ -1,6 +1,5 @@
1
- import { default as React } from 'react';
2
1
  import { UseCookieConsent } from '../../../hooks/use-cookie-consent.hook';
3
2
  export interface CookieConsentBannerProps {
4
3
  api: UseCookieConsent;
5
4
  }
6
- export declare const CookieConsentBanner: React.FC<CookieConsentBannerProps>;
5
+ export declare function CookieConsentBanner({ api }: CookieConsentBannerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function CookieConsentSettings(): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  export * from './AbyssCookieConsentProvider';
2
2
  export * from '../../../utils/privacy-link.constant';
3
- export * from './CookieConsentBanner.component';
4
- export * from './CookieConsentSettings.component';
3
+ export * from './CookieConsentBanner';
4
+ export * from './CookieConsentSettings';
5
5
  export * from '../../../hooks/use-cookie-consent.hook';
6
6
  export * from '../../../utils/cookie-storage.utils';
7
7
  export * from '../../../utils/cookie-consent-reconcile.utils';
@@ -2,3 +2,6 @@ export * from './InfectedDownloadModal/InfectedDownloadModal';
2
2
  export * from './CloudImport/CloudImport';
3
3
  export * from './ImportFromCloudModal/ImportFromCloudModal';
4
4
  export * from './QRCodeModal/QRCodeModal';
5
+ export * from './CookieConsent/AbyssCookieConsentProvider';
6
+ export * from './CookieConsent/CookieConsentBanner';
7
+ export * from './CookieConsent/CookieConsentSettings';
@@ -3,7 +3,11 @@ export interface FormFieldProps {
3
3
  label: string;
4
4
  /** A hint under the field, always shown. */
5
5
  help?: ReactNode;
6
- /** The error message: the field turns to the danger color and is marked invalid. */
6
+ /**
7
+ * The error message: the field turns to the danger color and is marked invalid. `true` marks the
8
+ * field invalid with no message line (the error is said elsewhere); `false`, `null` and `''`
9
+ * leave the field valid or without a line.
10
+ */
7
11
  error?: ReactNode;
8
12
  required?: boolean;
9
13
  /**
@@ -0,0 +1,40 @@
1
+ import { ChangeEvent, FocusEvent, KeyboardEvent, ReactNode, Ref } from 'react';
2
+ export interface PasswordFieldProps {
3
+ label: string;
4
+ name: string;
5
+ value: string;
6
+ onChange(event: ChangeEvent<HTMLInputElement>): void;
7
+ /** A hint under the field, always shown. */
8
+ help?: ReactNode;
9
+ /** The error message: the field turns to the danger color and is marked invalid. */
10
+ error?: ReactNode;
11
+ required?: boolean;
12
+ disabled?: boolean;
13
+ autoFocus?: boolean;
14
+ /**
15
+ * Password-manager hint. Always set it on a real auth form: `current-password` to sign in,
16
+ * `new-password` to sign up, reset or change. Leave it unset for a secret that belongs to no
17
+ * account (a protected link, an archive).
18
+ */
19
+ autoComplete?: string;
20
+ /** Id of the input; generated when omitted. */
21
+ id?: string;
22
+ inputRef?: Ref<HTMLInputElement>;
23
+ /** Raw attributes of the `input` with no dedicated prop (`passwordrules`). */
24
+ inputProps?: Record<string, string | number | boolean | undefined>;
25
+ placeholder?: string;
26
+ onBlur?(event: FocusEvent<HTMLInputElement>): void;
27
+ onKeyDown?(event: KeyboardEvent<HTMLInputElement>): void;
28
+ /** Where caps-lock detection goes (`event.getModifierState('CapsLock')`). */
29
+ onKeyUp?(event: KeyboardEvent<HTMLInputElement>): void;
30
+ /** `data-testid` of the input. */
31
+ testId?: string;
32
+ }
33
+ /**
34
+ * A password input on `FormField`: same label, hint and error contract as the other fields, and a
35
+ * 44 px toggle that reveals or hides the typed text. The toggle is in the tab order (WCAG 2.1.1: a
36
+ * keyboard user can reveal the text); it is a `type="button"`, so Enter in the input still submits
37
+ * the form instead of flipping the visibility. The field does no validation and shows no strength meter: the
38
+ * caller validates and passes `error`.
39
+ */
40
+ export declare function PasswordField({ label, name, value, onChange, help, error, required, disabled, autoFocus, autoComplete, id, inputRef, inputProps, placeholder, onBlur, onKeyDown, onKeyUp, testId, }: PasswordFieldProps): import("react/jsx-runtime").JSX.Element;
@@ -4,6 +4,7 @@ export * from './DateRangeField/DateRangeField';
4
4
  export * from './ColorField/ColorField';
5
5
  export * from './SegmentedControl/SegmentedControl';
6
6
  export * from './FormField/FormField';
7
+ export * from './PasswordField/PasswordField';
7
8
  export * from './NumberField/NumberField';
8
9
  export * from './SettingsRow/SettingsRow';
9
10
  export * from './CopyField/CopyField';
@@ -1,22 +1,7 @@
1
1
  import { ReactNode } from 'react';
2
- export declare enum ToastTone {
3
- Success = "success",
4
- Warning = "warning",
5
- Danger = "danger",
6
- Info = "info"
7
- }
8
- export interface ToastAction {
9
- label: string;
10
- onPress(): void;
11
- }
12
- export interface ToastOptions {
13
- tone: ToastTone;
14
- message: string;
15
- action?: ToastAction;
16
- }
17
- export interface ToastApi {
18
- show(toast: ToastOptions): void;
19
- }
2
+ import { ToastApi } from './toast-store';
3
+ export { toast, ToastTone } from './toast-store';
4
+ export type { ToastAction, ToastApi, ToastCallOptions, ToastOptions, ToastProgressOptions, ToastUpdate, } from './toast-store';
20
5
  export interface ToastProviderProps {
21
6
  children: ReactNode;
22
7
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The distance, from the bottom of the viewport, up to the top of what already occupies the bottom
3
+ * right corner (the cookie-consent banner). The toast region keeps above it, so a notification
4
+ * never covers the banner. Unset while nothing occupies the corner.
5
+ */
6
+ export declare const TOAST_CLEARANCE_VAR = "--abyss-toast-clearance";
@@ -0,0 +1,76 @@
1
+ export declare enum ToastTone {
2
+ Success = "success",
3
+ Warning = "warning",
4
+ Danger = "danger",
5
+ Info = "info"
6
+ }
7
+ export interface ToastAction {
8
+ label: string;
9
+ onPress(): void;
10
+ }
11
+ export interface ToastOptions {
12
+ tone: ToastTone;
13
+ message: string;
14
+ action?: ToastAction;
15
+ }
16
+ /** Options of `toast.success`, `toast.error`, `toast.info` and `toast.warning`. */
17
+ export interface ToastCallOptions {
18
+ action?: ToastAction;
19
+ /** Showing again with the same id replaces the notification instead of stacking another one. */
20
+ id?: string;
21
+ /** Time on screen in ms; defaults to `TOAST_DURATION`. */
22
+ durationMs?: number;
23
+ }
24
+ export interface ToastProgressOptions {
25
+ id?: string;
26
+ }
27
+ export interface ToastUpdate {
28
+ /** A tone ends the progress: the notification then leaves like any other. */
29
+ tone?: ToastTone;
30
+ message?: string;
31
+ /** Between 0 and 1; shown while the notification has no final tone. */
32
+ progress?: number;
33
+ }
34
+ /** A notification as the store holds it. `revision` restarts its timer whenever it changes. */
35
+ export interface ToastItem {
36
+ id: string;
37
+ tone: ToastTone;
38
+ message: string;
39
+ action?: ToastAction;
40
+ durationMs?: number;
41
+ /** True for a progress notification that has not received its final tone yet. */
42
+ pending: boolean;
43
+ progress?: number;
44
+ revision: number;
45
+ }
46
+ export interface ToastApi {
47
+ show(toast: ToastOptions): void;
48
+ }
49
+ type Listener = () => void;
50
+ /**
51
+ * Store read by the mounted `ToastProvider`. Calls made before it mounts are kept and shown when
52
+ * it does.
53
+ */
54
+ export declare const toastStore: {
55
+ subscribe(listener: Listener): () => void;
56
+ getItems(): readonly ToastItem[];
57
+ /** Claims the single display; returns its release function, or null if a provider already has it. */
58
+ attachProvider(): (() => void) | null;
59
+ };
60
+ /**
61
+ * Imperative notifications, usable from a hook, a utility or an axios interceptor. They show in the
62
+ * mounted `ToastProvider`. Every call returns the id of its notification.
63
+ */
64
+ export declare const toast: {
65
+ success: (message: string, options?: ToastCallOptions) => string;
66
+ error: (message: string, options?: ToastCallOptions) => string;
67
+ info: (message: string, options?: ToastCallOptions) => string;
68
+ warning: (message: string, options?: ToastCallOptions) => string;
69
+ /** A persistent notification, ended with `toast.update(id, { tone })`. */
70
+ progress(message: string, options?: ToastProgressOptions): string;
71
+ /** Does nothing when the notification has already left. */
72
+ update(id: string, changes: ToastUpdate): void;
73
+ /** Removes one notification, or all of them without an id. */
74
+ dismiss(id?: string): void;
75
+ };
76
+ export {};
@@ -0,0 +1,17 @@
1
+ import { ReactNode } from 'react';
2
+ export interface ErrorBoundaryProps {
3
+ /** Name of the app, carried by the technical detail so a report says where it came from. */
4
+ appName: string;
5
+ children: ReactNode;
6
+ /** Called when the user retries, before the children render again. */
7
+ onReset?(): void;
8
+ /** The boundary resets by itself when one of these values changes (the route, for instance). */
9
+ resetKeys?: unknown[];
10
+ /** Fills the viewport (the error replaces the whole app); otherwise the block sits in its slot. */
11
+ fullHeight?: boolean;
12
+ }
13
+ /**
14
+ * Catches the render errors of its children, reports them to the front's RUM and shows an error
15
+ * block in their place, with « Réessayer » and the technical detail on demand.
16
+ */
17
+ export declare function ErrorBoundary({ appName, children, onReset, resetKeys, fullHeight, }: ErrorBoundaryProps): import("react/jsx-runtime").JSX.Element;
@@ -14,7 +14,9 @@ export interface PageStateEmpty {
14
14
  action?: ReactNode;
15
15
  }
16
16
  export interface PageStateError {
17
- /** Replaces the generic description; the title stays « Le chargement a échoué ». */
17
+ /** Replaces the title « Le chargement a échoué » (a crash is not a failed load). */
18
+ title?: string;
19
+ /** Replaces the generic description; the title stays the default one unless `title` is set. */
18
20
  message?: string;
19
21
  onRetry(): void;
20
22
  }
@@ -1,2 +1,3 @@
1
1
  export * from './PageState/PageState';
2
2
  export * from './Callout/Callout';
3
+ export * from './ErrorBoundary/ErrorBoundary';
@@ -1,2 +1,2 @@
1
- export * from './legacy/components/CookieConsent/index'
1
+ export * from './components/business/CookieConsent/index'
2
2
  export {}
@@ -1,20 +1,19 @@
1
- import { A as s, c as a, C as n, D as C, R as i, V as t, d as r, r as A, e as k, u as c, b as l, a as f, w as b } from "./AbyssCookieConsentProvider-Ds99df0E.js";
2
- import { C as u } from "./CookieConsentSettings.component-DoWLHqw5.js";
3
- import { f as E } from "./use-rich-intl.hook-BETUyCkW.js";
1
+ import { A as e, d as a, C as n, b as C, D as i, R as t, V as r, e as A, r as k, f as c, u as l, c as f, a as b, w as u } from "./CookieConsentSettings-DyJGEnVA.js";
2
+ import { f as E } from "./Surface-B_J_I_1i.js";
4
3
  export {
5
- s as AbyssCookieConsentProvider,
4
+ e as AbyssCookieConsentProvider,
6
5
  a as COOKIE_NAME,
7
6
  n as CookieConsentBanner,
8
- u as CookieConsentSettings,
9
- C as DEFAULT_PRIVACY_HREF,
10
- i as ReconcileAction,
11
- t as VALIDITY_DAYS,
12
- r as clearCookie,
7
+ C as CookieConsentSettings,
8
+ i as DEFAULT_PRIVACY_HREF,
9
+ t as ReconcileAction,
10
+ r as VALIDITY_DAYS,
11
+ A as clearCookie,
13
12
  E as flattenTranslations,
14
- A as readCookie,
15
- k as reconcile,
16
- c as useAbyssCookieConsent,
17
- l as useCookieConsent,
18
- f as useOptionalAbyssCookieConsent,
19
- b as writeCookie
13
+ k as readCookie,
14
+ c as reconcile,
15
+ l as useAbyssCookieConsent,
16
+ f as useCookieConsent,
17
+ b as useOptionalAbyssCookieConsent,
18
+ u as writeCookie
20
19
  };
@@ -0,0 +1,16 @@
1
+ /** The page of abyss-docs that says what a demo account blocks (same base as the legacy layout's documentation link). */
2
+ export declare const DEMO_DOCS_URL = "https://docs.abyss-project.fr/abyss-project/demo-account";
3
+ /** CSS variable carrying the height of a pinned banner, read by the fixed chrome pushed below it. */
4
+ export declare const DEMO_BANNER_HEIGHT_VAR = "--demo-banner-height";
5
+ /**
6
+ * The permanent banner of a demo account: its group, when the group expires, « Réinitialiser »
7
+ * (after a confirmation that names the whole group) and « En savoir plus » (abyss-docs). It has no
8
+ * close button. Renders nothing outside a demo, or while the group is loading.
9
+ *
10
+ * `pinned` is for an app that mounts it at the root, above its router: the banner then stays on top
11
+ * of the page and the fixed header and sidebar of the app start under it. A banner placed inside a
12
+ * layout, in the flow of the page, keeps the default.
13
+ */
14
+ export declare const DemoBanner: ({ pinned }: {
15
+ pinned?: boolean;
16
+ }) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from './DemoBanner';
@@ -0,0 +1,7 @@
1
+ import { AxiosInstance } from 'axios';
2
+ /**
3
+ * Tells the user, through `notify`, that a demo account may not do what it just tried (the API
4
+ * answers 403 `DEMO_ACTION_BLOCKED`). The error is still rejected so callers keep their own
5
+ * handling. Returns the function that detaches the interceptor.
6
+ */
7
+ export declare const attachDemoBlockedInterceptor: (instance: AxiosInstance, notify: (message: string) => void) => (() => void);
@@ -0,0 +1,17 @@
1
+ declare const _default: {
2
+ banner: {
3
+ title: string;
4
+ summary: string;
5
+ 'expires-in': string;
6
+ 'expires-today': string;
7
+ reset: string;
8
+ 'learn-more': string;
9
+ 'reset-dialog': {
10
+ title: string;
11
+ body: string;
12
+ confirm: string;
13
+ };
14
+ };
15
+ blocked: string;
16
+ };
17
+ export default _default;
@@ -0,0 +1,17 @@
1
+ declare const _default: {
2
+ banner: {
3
+ title: string;
4
+ summary: string;
5
+ 'expires-in': string;
6
+ 'expires-today': string;
7
+ reset: string;
8
+ 'learn-more': string;
9
+ 'reset-dialog': {
10
+ title: string;
11
+ body: string;
12
+ confirm: string;
13
+ };
14
+ };
15
+ blocked: string;
16
+ };
17
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export * from './DemoBanner';
2
+ export * from './use-demo-account.hook';
3
+ export * from './demo-blocked.interceptor';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ export interface DemoGroup {
2
+ label: string;
3
+ expiresAt: Date;
4
+ }
5
+ export interface DemoAccount {
6
+ /** The signed-in user belongs to a demo group. */
7
+ isDemo: boolean;
8
+ /** The group, once loaded; `null` outside a demo and while it loads or cannot be read. */
9
+ group: DemoGroup | null;
10
+ /** Resets the whole group to its seeded state (all its accounts), then reloads the group. */
11
+ reset(): Promise<void>;
12
+ }
13
+ /**
14
+ * The demo state of the signed-in user (`IUser.demoGroupId`) and its group (`GET /demo/me`).
15
+ * Outside an `<AuthProvider>` or signed out, it is not a demo. The group is only read for a demo
16
+ * user; a group that cannot be read leaves `group` null (the server enforces the demo either way,
17
+ * the banner only announces it).
18
+ */
19
+ export declare const useDemoAccount: () => DemoAccount;