@equinor/fusion-framework-react-app 9.0.8 → 10.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 (134) hide show
  1. package/CHANGELOG.md +85 -14
  2. package/README.md +176 -99
  3. package/dist/esm/ag-grid/useTheme.js +7 -0
  4. package/dist/esm/ag-grid/useTheme.js.map +1 -1
  5. package/dist/esm/analytics/index.js +8 -0
  6. package/dist/esm/analytics/index.js.map +1 -1
  7. package/dist/esm/analytics/useTrackFeature.js +17 -1
  8. package/dist/esm/analytics/useTrackFeature.js.map +1 -1
  9. package/dist/esm/apploader/Apploader.js +1 -1
  10. package/dist/esm/apploader/Apploader.js.map +1 -1
  11. package/dist/esm/apploader/index.js +8 -0
  12. package/dist/esm/apploader/index.js.map +1 -1
  13. package/dist/esm/bookmark/index.js +8 -0
  14. package/dist/esm/bookmark/index.js.map +1 -1
  15. package/dist/esm/context/index.js +8 -0
  16. package/dist/esm/context/index.js.map +1 -1
  17. package/dist/esm/context/useContextProvider.js +6 -0
  18. package/dist/esm/context/useContextProvider.js.map +1 -1
  19. package/dist/esm/context/useCurrentContext.js +14 -0
  20. package/dist/esm/context/useCurrentContext.js.map +1 -1
  21. package/dist/esm/create-legacy-app.js +13 -0
  22. package/dist/esm/create-legacy-app.js.map +1 -1
  23. package/dist/esm/feature-flag/index.js.map +1 -1
  24. package/dist/esm/feature-flag/useFeature.js +20 -4
  25. package/dist/esm/feature-flag/useFeature.js.map +1 -1
  26. package/dist/esm/framework/index.js +8 -1
  27. package/dist/esm/framework/index.js.map +1 -1
  28. package/dist/esm/framework/useFrameworkCurrentContext.js +9 -0
  29. package/dist/esm/framework/useFrameworkCurrentContext.js.map +1 -1
  30. package/dist/esm/help-center/useHelpCenter.js +12 -1
  31. package/dist/esm/help-center/useHelpCenter.js.map +1 -1
  32. package/dist/esm/http/index.js +9 -0
  33. package/dist/esm/http/index.js.map +1 -1
  34. package/dist/esm/http/selectors.js +10 -0
  35. package/dist/esm/http/selectors.js.map +1 -0
  36. package/dist/esm/index.js +16 -2
  37. package/dist/esm/index.js.map +1 -1
  38. package/dist/esm/make-component.js +1 -1
  39. package/dist/esm/make-component.js.map +1 -1
  40. package/dist/esm/msal/index.js +13 -0
  41. package/dist/esm/msal/index.js.map +1 -1
  42. package/dist/esm/msal/useAccessToken.js +15 -3
  43. package/dist/esm/msal/useAccessToken.js.map +1 -1
  44. package/dist/esm/msal/useCurrentAccount.js +12 -2
  45. package/dist/esm/msal/useCurrentAccount.js.map +1 -1
  46. package/dist/esm/msal/useToken.js +19 -3
  47. package/dist/esm/msal/useToken.js.map +1 -1
  48. package/dist/esm/navigation/index.js +8 -0
  49. package/dist/esm/navigation/index.js.map +1 -1
  50. package/dist/esm/navigation/useNavigationModule.js +6 -1
  51. package/dist/esm/navigation/useNavigationModule.js.map +1 -1
  52. package/dist/esm/navigation/useRouter.js +23 -4
  53. package/dist/esm/navigation/useRouter.js.map +1 -1
  54. package/dist/esm/render-app.js +22 -1
  55. package/dist/esm/render-app.js.map +1 -1
  56. package/dist/esm/render-component.js +30 -23
  57. package/dist/esm/render-component.js.map +1 -1
  58. package/dist/esm/settings/index.js +8 -0
  59. package/dist/esm/settings/index.js.map +1 -1
  60. package/dist/esm/useAppModule.js +13 -5
  61. package/dist/esm/useAppModule.js.map +1 -1
  62. package/dist/esm/useAppModules.js +9 -3
  63. package/dist/esm/useAppModules.js.map +1 -1
  64. package/dist/esm/version.js +1 -1
  65. package/dist/esm/version.js.map +1 -1
  66. package/dist/tsconfig.tsbuildinfo +1 -1
  67. package/dist/types/ag-grid/useTheme.d.ts +7 -0
  68. package/dist/types/analytics/index.d.ts +8 -0
  69. package/dist/types/analytics/useTrackFeature.d.ts +17 -1
  70. package/dist/types/apploader/Apploader.d.ts +3 -2
  71. package/dist/types/apploader/index.d.ts +8 -0
  72. package/dist/types/bookmark/index.d.ts +8 -0
  73. package/dist/types/context/index.d.ts +8 -0
  74. package/dist/types/context/useContextProvider.d.ts +6 -0
  75. package/dist/types/context/useCurrentContext.d.ts +14 -0
  76. package/dist/types/create-legacy-app.d.ts +13 -0
  77. package/dist/types/feature-flag/index.d.ts +8 -0
  78. package/dist/types/feature-flag/useFeature.d.ts +20 -4
  79. package/dist/types/framework/index.d.ts +8 -0
  80. package/dist/types/framework/useFrameworkCurrentContext.d.ts +9 -0
  81. package/dist/types/help-center/useHelpCenter.d.ts +12 -1
  82. package/dist/types/http/index.d.ts +9 -0
  83. package/dist/types/http/selectors.d.ts +9 -0
  84. package/dist/types/index.d.ts +18 -1
  85. package/dist/types/make-component.d.ts +15 -0
  86. package/dist/types/msal/index.d.ts +13 -0
  87. package/dist/types/msal/useAccessToken.d.ts +15 -3
  88. package/dist/types/msal/useCurrentAccount.d.ts +12 -2
  89. package/dist/types/msal/useToken.d.ts +19 -3
  90. package/dist/types/navigation/index.d.ts +8 -0
  91. package/dist/types/navigation/useNavigationModule.d.ts +6 -1
  92. package/dist/types/navigation/useRouter.d.ts +23 -4
  93. package/dist/types/render-app.d.ts +22 -1
  94. package/dist/types/render-component.d.ts +16 -1
  95. package/dist/types/settings/index.d.ts +8 -0
  96. package/dist/types/useAppModule.d.ts +13 -5
  97. package/dist/types/useAppModules.d.ts +9 -3
  98. package/dist/types/version.d.ts +1 -1
  99. package/package.json +35 -27
  100. package/src/__tests__/render-app.test.tsx +113 -0
  101. package/src/ag-grid/useTheme.ts +7 -0
  102. package/src/analytics/index.ts +8 -0
  103. package/src/analytics/useTrackFeature.ts +17 -1
  104. package/src/apploader/Apploader.tsx +3 -3
  105. package/src/apploader/index.ts +8 -0
  106. package/src/bookmark/index.ts +8 -0
  107. package/src/context/index.ts +8 -0
  108. package/src/context/useContextProvider.ts +6 -0
  109. package/src/context/useCurrentContext.ts +14 -0
  110. package/src/create-legacy-app.tsx +13 -0
  111. package/src/feature-flag/index.ts +8 -0
  112. package/src/feature-flag/useFeature.ts +20 -4
  113. package/src/framework/index.ts +8 -1
  114. package/src/framework/useFrameworkCurrentContext.ts +9 -0
  115. package/src/help-center/useHelpCenter.ts +12 -1
  116. package/src/http/index.ts +9 -0
  117. package/src/http/selectors.ts +9 -0
  118. package/src/index.ts +20 -2
  119. package/src/make-component.tsx +16 -1
  120. package/src/msal/index.ts +13 -0
  121. package/src/msal/useAccessToken.ts +15 -3
  122. package/src/msal/useCurrentAccount.ts +12 -2
  123. package/src/msal/useToken.ts +19 -3
  124. package/src/navigation/index.ts +8 -0
  125. package/src/navigation/useNavigationModule.ts +6 -1
  126. package/src/navigation/useRouter.ts +23 -4
  127. package/src/render-app.ts +22 -1
  128. package/src/render-component.tsx +36 -27
  129. package/src/settings/index.ts +8 -0
  130. package/src/useAppModule.ts +13 -5
  131. package/src/useAppModules.ts +11 -5
  132. package/src/version.ts +1 -1
  133. package/tsconfig.json +1 -1
  134. package/vitest.config.ts +15 -0
@@ -5,9 +5,25 @@ import type { AuthenticationResult } from '@equinor/fusion-framework-module-msal
5
5
  import useAppModule from '../useAppModule';
6
6
 
7
7
  /**
8
- * Custom hook for acquiring an authentication token using MSAL.
9
- * @param req - The authentication request.
10
- * @returns An object containing the acquired token, pending state, and error.
8
+ * React hook that acquires a full MSAL {@link AuthenticationResult} for the
9
+ * requested scopes.
10
+ *
11
+ * The hook attempts silent acquisition first and falls back to an interactive
12
+ * prompt when required by the MSAL provider.
13
+ *
14
+ * @param req - The token request containing the `scopes` to acquire.
15
+ * @param req.scopes - Array of scope strings (e.g. `['User.Read']`).
16
+ * @returns An object with:
17
+ * - `token` – the full {@link AuthenticationResult}, or `undefined` while pending.
18
+ * - `pending` – `true` while the token is being acquired.
19
+ * - `error` – any error encountered during acquisition.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * const { token, pending } = useToken({ scopes: ['User.Read'] });
24
+ * if (pending) return <Spinner />;
25
+ * console.log('ID token:', token?.idToken);
26
+ * ```
11
27
  */
12
28
  export const useToken = (req: {
13
29
  scopes: string[];
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Navigation sub-path entry-point.
3
+ *
4
+ * Provides hooks for accessing the Fusion navigation module and creating
5
+ * client-side routers compatible with `react-router`.
6
+ *
7
+ * @packageDocumentation
8
+ */
1
9
  export { useNavigationModule } from './useNavigationModule';
2
10
  export { useRouter } from './useRouter';
@@ -1,5 +1,10 @@
1
1
  import useAppModule from '../useAppModule';
2
2
  import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
3
3
 
4
- /** hook for getting the navigation provider (if enabled!) */
4
+ /**
5
+ * React hook that resolves the application-scoped navigation module provider.
6
+ *
7
+ * @returns The navigation provider instance.
8
+ * @throws If the navigation module has not been enabled for the application.
9
+ */
5
10
  export const useNavigationModule = (): INavigationProvider => useAppModule('navigation');
@@ -3,10 +3,29 @@ import { useNavigationModule } from './useNavigationModule';
3
3
  import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
4
4
 
5
5
  /**
6
- * create a router for react routing
7
- * @see {@link [docs](https://equinor.github.io/fusion-framework/modules/navigation/)}
8
- * @see {@link [react-router](https://reactrouter.com/en/main/routers/create-browser-router)}
9
- * @param routes router objects __(must be static | memorized)__
6
+ * React hook that creates a router instance for client-side navigation.
7
+ *
8
+ * The `routes` argument **must** be static or memoised to avoid re-creating
9
+ * the router on every render.
10
+ *
11
+ * @param routes - An array of route objects compatible with
12
+ * `INavigationProvider.createRouter`.
13
+ * @returns A router instance to pass to `<RouterProvider>`.
14
+ *
15
+ * @see {@link https://equinor.github.io/fusion-framework/modules/navigation/ | Fusion navigation docs}
16
+ * @see {@link https://reactrouter.com/en/main/routers/create-browser-router | react-router docs}
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { useRouter } from '@equinor/fusion-framework-react-app/navigation';
21
+ * import { RouterProvider } from 'react-router-dom';
22
+ *
23
+ * const routes = [{ path: '/', element: <Home /> }];
24
+ * const App = () => {
25
+ * const router = useRouter(routes);
26
+ * return <RouterProvider router={router} />;
27
+ * };
28
+ * ```
10
29
  */
11
30
  export const useRouter = (
12
31
  routes: Parameters<INavigationProvider['createRouter']>[0],
package/src/render-app.ts CHANGED
@@ -3,7 +3,28 @@ import { renderComponent, type RenderTeardown } from './render-component';
3
3
 
4
4
  import type { ComponentRenderArgs } from './create-component';
5
5
 
6
- /** @deprecated */
6
+ /**
7
+ * Creates a render function for a Fusion React application.
8
+ *
9
+ * Wraps {@link createComponent} and {@link renderComponent} into a single factory:
10
+ * call the returned function with an `HTMLElement` and `ComponentRenderArgs` to
11
+ * mount the app using React 18's `createRoot` API.
12
+ *
13
+ * @param componentArgs - Arguments forwarded to {@link createComponent} (the React
14
+ * component to render and an optional module-configuration callback).
15
+ * @returns A mount function that accepts a DOM element and render args, and returns
16
+ * a {@link RenderTeardown} callback to unmount the application.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { renderApp } from '@equinor/fusion-framework-react-app';
21
+ * import { App } from './App';
22
+ * import { configure } from './config';
23
+ *
24
+ * export const render = renderApp(App, configure);
25
+ * export default render;
26
+ * ```
27
+ */
7
28
  export const renderApp = (...componentArgs: Parameters<typeof createComponent>) => {
8
29
  const renderer = renderComponent(createComponent(...componentArgs));
9
30
  return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
@@ -1,46 +1,55 @@
1
1
  import { Suspense, StrictMode } from 'react';
2
2
  import type { FunctionComponent } from 'react';
3
+ import { createRoot, type Root } from 'react-dom/client';
3
4
  import type { ComponentRenderArgs, ComponentRenderer } from './create-component';
4
- import ReactDOM from 'react-dom';
5
5
 
6
+ /**
7
+ * Callback returned after mounting an application; invoke it to unmount and clean
8
+ * up the React root.
9
+ */
6
10
  export type RenderTeardown = VoidFunction;
7
11
 
8
- /** @deprecated */
9
- export const renderComponent = (renderer: ComponentRenderer) => {
10
- return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
11
- const Component = renderer(args.fusion, args.env);
12
- return render(el, Component);
13
- };
14
- };
15
-
12
+ /**
13
+ * Renders a React component into a DOM element using React 18's `createRoot` API.
14
+ *
15
+ * The component is wrapped in `<StrictMode>` and `<Suspense>` with a basic
16
+ * loading fallback.
17
+ *
18
+ * @param el - The DOM element to render into.
19
+ * @param Component - The React function component to render.
20
+ * @returns A {@link RenderTeardown} callback that unmounts the component.
21
+ */
16
22
  const render = (el: Element, Component: FunctionComponent): RenderTeardown => {
17
- // eslint-disable-next-line react/no-deprecated
18
- ReactDOM.render(
23
+ const root: Root = createRoot(el);
24
+ root.render(
19
25
  <StrictMode>
20
26
  <Suspense fallback={<p>loading app</p>}>
21
27
  <Component />
22
28
  </Suspense>
23
29
  </StrictMode>,
24
- el,
25
30
  );
26
31
  return () => {
27
- // eslint-disable-next-line react/no-deprecated
28
- ReactDOM.unmountComponentAtNode(el);
32
+ root.unmount();
29
33
  };
30
34
  };
31
35
 
32
- // const render = (el: Element, Component: FunctionComponent): RenderTeardown => {
33
- // const root = createRoot(el);
34
- // root.render(
35
- // <StrictMode>
36
- // <Suspense fallback={<p>loading app</p>}>
37
- // <Component />
38
- // </Suspense>
39
- // </StrictMode>
40
- // );
41
- // return () => {
42
- // root.unmount();
43
- // };
44
- // };
36
+ /**
37
+ * Creates a mount function from a {@link ComponentRenderer}.
38
+ *
39
+ * The returned function accepts a target `HTMLElement` and
40
+ * {@link ComponentRenderArgs}, resolves the lazy component via the renderer,
41
+ * and mounts it with React 18's `createRoot`.
42
+ *
43
+ * @param renderer - A {@link ComponentRenderer} that produces a lazy component
44
+ * from Fusion and environment arguments.
45
+ * @returns A function `(el, args) => RenderTeardown` that mounts the app and
46
+ * returns a teardown callback.
47
+ */
48
+ export const renderComponent = (renderer: ComponentRenderer) => {
49
+ return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
50
+ const Component = renderer(args.fusion, args.env);
51
+ return render(el, Component);
52
+ };
53
+ };
45
54
 
46
55
  export default renderComponent;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Settings sub-path entry-point.
3
+ *
4
+ * Provides hooks for reading and updating per-application user settings
5
+ * that are persisted by the Fusion platform.
6
+ *
7
+ * @packageDocumentation
8
+ */
1
9
  export { useAppSetting } from './useAppSetting';
2
10
  export { useAppSettings } from './useAppSettings';
3
11
 
@@ -9,12 +9,20 @@ import type {
9
9
  import { useAppModules } from './useAppModules';
10
10
 
11
11
  /**
12
- * Retrieves the specified app module from the app scope.
12
+ * React hook that retrieves a single module instance from the application scope.
13
13
  *
14
- * @template TType - The type of the app module.
15
- * @template TKey - The key of the app module.
16
- * @param module - The key of the app module to retrieve.
17
- * @returns The app module instance if found, otherwise throws an error.
14
+ * @template TType - The concrete module type (e.g. `ContextModule`). Pass
15
+ * `unknown` to infer the type from the key.
16
+ * @template TKey - The string key used to look up the module.
17
+ * @param module - The key identifying the module to retrieve.
18
+ * @returns The resolved module instance.
19
+ * @throws If the requested module is not registered in the application scope.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * const auth = useAppModule('auth');
24
+ * auth.acquireAccessToken().then(console.log);
25
+ * ```
18
26
  */
19
27
  export function useAppModule<
20
28
  TType extends AnyModule | unknown = unknown,
@@ -1,15 +1,21 @@
1
- import type { AppModulesInstance } from '@equinor/fusion-framework-app';
1
+ import type { AppModules, AppModulesInstance } from '@equinor/fusion-framework-app';
2
2
  import type { AnyModule } from '@equinor/fusion-framework-module';
3
3
  import { useModules } from '@equinor/fusion-framework-react-module';
4
4
 
5
5
  /**
6
- * Custom hook that returns an instance of the app modules.
6
+ * React hook that returns the full set of initialised application-scoped modules.
7
7
  *
8
- * @template T - The type of the app modules.
9
- * @returns An instance of the app modules.
8
+ * @template T - Optional array of additional module types beyond the defaults.
9
+ * @returns The {@link AppModulesInstance} containing all registered modules.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const modules = useAppModules();
14
+ * console.log(Object.keys(modules));
15
+ * ```
10
16
  */
11
17
  export const useAppModules = <
12
18
  T extends Array<AnyModule> | unknown = unknown,
13
- >(): AppModulesInstance<T> => useModules<AppModulesInstance<T>>();
19
+ >(): AppModulesInstance<T> => useModules<AppModules<T>>() as AppModulesInstance<T>;
14
20
 
15
21
  export default useAppModules;
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '9.0.8';
2
+ export const version = '10.0.0';
package/tsconfig.json CHANGED
@@ -38,5 +38,5 @@
38
38
  }
39
39
  ],
40
40
  "include": ["src/**/*"],
41
- "exclude": ["node_modules", "lib"]
41
+ "exclude": ["node_modules", "lib", "src/__tests__/**/*"]
42
42
  }
@@ -0,0 +1,15 @@
1
+ import { defineProject } from 'vitest/config';
2
+
3
+ import { name, version } from './package.json';
4
+
5
+ export default defineProject({
6
+ resolve: {
7
+ // @ts-expect-error -- tsconfigPaths is a Vite 8 option; vitest 4.x ships Vite 7 types
8
+ tsconfigPaths: true,
9
+ },
10
+ test: {
11
+ include: ['src/__tests__/**'],
12
+ name: `${name}@${version}`,
13
+ environment: 'happy-dom',
14
+ },
15
+ });