@equinor/fusion-framework-react-app 9.0.9-next.0 → 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 (127) hide show
  1. package/CHANGELOG.md +80 -12
  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/index.js +8 -0
  10. package/dist/esm/apploader/index.js.map +1 -1
  11. package/dist/esm/bookmark/index.js +8 -0
  12. package/dist/esm/bookmark/index.js.map +1 -1
  13. package/dist/esm/context/index.js +8 -0
  14. package/dist/esm/context/index.js.map +1 -1
  15. package/dist/esm/context/useContextProvider.js +6 -0
  16. package/dist/esm/context/useContextProvider.js.map +1 -1
  17. package/dist/esm/context/useCurrentContext.js +14 -0
  18. package/dist/esm/context/useCurrentContext.js.map +1 -1
  19. package/dist/esm/create-legacy-app.js +13 -0
  20. package/dist/esm/create-legacy-app.js.map +1 -1
  21. package/dist/esm/feature-flag/index.js.map +1 -1
  22. package/dist/esm/feature-flag/useFeature.js +20 -4
  23. package/dist/esm/feature-flag/useFeature.js.map +1 -1
  24. package/dist/esm/framework/index.js +8 -1
  25. package/dist/esm/framework/index.js.map +1 -1
  26. package/dist/esm/framework/useFrameworkCurrentContext.js +9 -0
  27. package/dist/esm/framework/useFrameworkCurrentContext.js.map +1 -1
  28. package/dist/esm/help-center/useHelpCenter.js +12 -1
  29. package/dist/esm/help-center/useHelpCenter.js.map +1 -1
  30. package/dist/esm/http/index.js +9 -0
  31. package/dist/esm/http/index.js.map +1 -1
  32. package/dist/esm/http/selectors.js +8 -0
  33. package/dist/esm/http/selectors.js.map +1 -1
  34. package/dist/esm/index.js +15 -0
  35. package/dist/esm/index.js.map +1 -1
  36. package/dist/esm/make-component.js.map +1 -1
  37. package/dist/esm/msal/index.js +13 -0
  38. package/dist/esm/msal/index.js.map +1 -1
  39. package/dist/esm/msal/useAccessToken.js +15 -3
  40. package/dist/esm/msal/useAccessToken.js.map +1 -1
  41. package/dist/esm/msal/useCurrentAccount.js +12 -2
  42. package/dist/esm/msal/useCurrentAccount.js.map +1 -1
  43. package/dist/esm/msal/useToken.js +19 -3
  44. package/dist/esm/msal/useToken.js.map +1 -1
  45. package/dist/esm/navigation/index.js +8 -0
  46. package/dist/esm/navigation/index.js.map +1 -1
  47. package/dist/esm/navigation/useNavigationModule.js +6 -1
  48. package/dist/esm/navigation/useNavigationModule.js.map +1 -1
  49. package/dist/esm/navigation/useRouter.js +23 -4
  50. package/dist/esm/navigation/useRouter.js.map +1 -1
  51. package/dist/esm/render-app.js +19 -4
  52. package/dist/esm/render-app.js.map +1 -1
  53. package/dist/esm/render-component.js +16 -8
  54. package/dist/esm/render-component.js.map +1 -1
  55. package/dist/esm/settings/index.js +8 -0
  56. package/dist/esm/settings/index.js.map +1 -1
  57. package/dist/esm/useAppModule.js +13 -5
  58. package/dist/esm/useAppModule.js.map +1 -1
  59. package/dist/esm/useAppModules.js +9 -3
  60. package/dist/esm/useAppModules.js.map +1 -1
  61. package/dist/esm/version.js +1 -1
  62. package/dist/esm/version.js.map +1 -1
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/dist/types/ag-grid/useTheme.d.ts +7 -0
  65. package/dist/types/analytics/index.d.ts +8 -0
  66. package/dist/types/analytics/useTrackFeature.d.ts +17 -1
  67. package/dist/types/apploader/index.d.ts +8 -0
  68. package/dist/types/bookmark/index.d.ts +8 -0
  69. package/dist/types/context/index.d.ts +8 -0
  70. package/dist/types/context/useContextProvider.d.ts +6 -0
  71. package/dist/types/context/useCurrentContext.d.ts +14 -0
  72. package/dist/types/create-legacy-app.d.ts +13 -0
  73. package/dist/types/feature-flag/index.d.ts +8 -0
  74. package/dist/types/feature-flag/useFeature.d.ts +20 -4
  75. package/dist/types/framework/index.d.ts +8 -0
  76. package/dist/types/framework/useFrameworkCurrentContext.d.ts +9 -0
  77. package/dist/types/help-center/useHelpCenter.d.ts +12 -1
  78. package/dist/types/http/index.d.ts +9 -0
  79. package/dist/types/http/selectors.d.ts +8 -0
  80. package/dist/types/index.d.ts +15 -0
  81. package/dist/types/make-component.d.ts +15 -0
  82. package/dist/types/msal/index.d.ts +13 -0
  83. package/dist/types/msal/useAccessToken.d.ts +15 -3
  84. package/dist/types/msal/useCurrentAccount.d.ts +12 -2
  85. package/dist/types/msal/useToken.d.ts +19 -3
  86. package/dist/types/navigation/index.d.ts +8 -0
  87. package/dist/types/navigation/useNavigationModule.d.ts +6 -1
  88. package/dist/types/navigation/useRouter.d.ts +23 -4
  89. package/dist/types/render-app.d.ts +19 -4
  90. package/dist/types/render-component.d.ts +13 -4
  91. package/dist/types/settings/index.d.ts +8 -0
  92. package/dist/types/useAppModule.d.ts +13 -5
  93. package/dist/types/useAppModules.d.ts +9 -3
  94. package/dist/types/version.d.ts +1 -1
  95. package/package.json +22 -23
  96. package/src/ag-grid/useTheme.ts +7 -0
  97. package/src/analytics/index.ts +8 -0
  98. package/src/analytics/useTrackFeature.ts +17 -1
  99. package/src/apploader/index.ts +8 -0
  100. package/src/bookmark/index.ts +8 -0
  101. package/src/context/index.ts +8 -0
  102. package/src/context/useContextProvider.ts +6 -0
  103. package/src/context/useCurrentContext.ts +14 -0
  104. package/src/create-legacy-app.tsx +13 -0
  105. package/src/feature-flag/index.ts +8 -0
  106. package/src/feature-flag/useFeature.ts +20 -4
  107. package/src/framework/index.ts +8 -1
  108. package/src/framework/useFrameworkCurrentContext.ts +9 -0
  109. package/src/help-center/useHelpCenter.ts +12 -1
  110. package/src/http/index.ts +9 -0
  111. package/src/http/selectors.ts +8 -0
  112. package/src/index.ts +16 -0
  113. package/src/make-component.tsx +15 -0
  114. package/src/msal/index.ts +13 -0
  115. package/src/msal/useAccessToken.ts +15 -3
  116. package/src/msal/useCurrentAccount.ts +12 -2
  117. package/src/msal/useToken.ts +19 -3
  118. package/src/navigation/index.ts +8 -0
  119. package/src/navigation/useNavigationModule.ts +6 -1
  120. package/src/navigation/useRouter.ts +23 -4
  121. package/src/render-app.ts +19 -4
  122. package/src/render-component.tsx +20 -8
  123. package/src/settings/index.ts +8 -0
  124. package/src/useAppModule.ts +13 -5
  125. package/src/useAppModules.ts +9 -3
  126. package/src/version.ts +1 -1
  127. package/vitest.config.ts +4 -9
package/CHANGELOG.md CHANGED
@@ -1,21 +1,89 @@
1
1
  # Change Log
2
2
 
3
- ## 9.0.9-next.0
3
+ ## 10.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - abffa53: Major version bump for Fusion Framework React 19 release.
8
+
9
+ All packages are bumped to the next major version as part of the React 19 upgrade. This release drops support for React versions below 18 and includes breaking changes across the framework.
10
+
11
+ **Breaking changes:**
12
+ - Peer dependencies now require React 18 or 19 (`^18.0.0 || ^19.0.0`)
13
+ - React Router upgraded from v6 to v7
14
+ - Navigation module refactored with new history API
15
+ - `renderComponent` and `renderApp` now use `createRoot` API
16
+
17
+ **Migration:**
18
+ - Update your React version to 18.0.0 or higher before upgrading
19
+ - Replace `NavigationProvider.createRouter()` with `@equinor/fusion-framework-react-router`
20
+ - See individual package changelogs for package-specific migration steps
21
+
22
+ - abffa53: Modernize `renderComponent` and `renderApp` to use React 18's `createRoot` API. These functions are no longer deprecated.
23
+
24
+ The legacy `ReactDOM.render` path has been removed. Both functions now use `createRoot` internally, matching React 18+ best practices. No migration is required if you already use React 18+.
25
+
26
+ - abffa53: Upgrade to React 19 and remove support for React versions lower than 18.
27
+
28
+ **Breaking changes:**
29
+ - Peer dependencies now require React 18 or 19 (`^18.0.0 || ^19.0.0`)
30
+ - React 16 and 17 are no longer supported
31
+ - Dev dependencies upgraded to React 19.2.1 and @types/react 19.2.7
32
+
33
+ **Migration:**
34
+ - Update your React version to 18.0.0 or higher before upgrading these packages
35
+ - If using React 16 or 17, upgrade to React 18 or 19 first
36
+
37
+ Closes https://github.com/equinor/fusion-framework/issues/3504
38
+
39
+ ### Minor Changes
40
+
41
+ - abffa53: Export `Fusion` type from `@equinor/fusion-framework-react-app` for better type reusability.
42
+
43
+ The `Fusion` type is now available directly from the react-app package:
44
+
45
+ ```typescript
46
+ import type { Fusion } from "@equinor/fusion-framework-react-app";
47
+ ```
4
48
 
5
49
  ### Patch Changes
6
50
 
7
- - [#3820](https://github.com/equinor/fusion-framework/pull/3820) [`f647825`](https://github.com/equinor/fusion-framework/commit/f647825cb5712763b09dafda21fd996211c78b78) Thanks [@odinr](https://github.com/odinr)! - relase next
51
+ - abffa53: Add test suite for `renderApp` function using Vitest and React Testing Library.
52
+
53
+ Includes test coverage for component rendering, teardown functionality, and React 18 createRoot integration.
54
+
55
+ - aaa3f74: fix(security): address undici multiple vulnerabilities (CVE-2026-1524, 1527, 1528, 2581)
56
+
57
+ Upgrade undici from 7.22.0 to 7.24.3 to fix multiple security vulnerabilities affecting WebSocket parsing, HTTP header validation, and request deduplication:
58
+ - **CVE-2026-1528** (HIGH): WebSocket 64-bit length integer overflow causing process crash
59
+ - **CVE-2026-1524** (MODERATE): HTTP/1.1 response field header injection
60
+ - **CVE-2026-1527** (MODERATE): CRLF injection via upgrade option enabling protocol smuggling
61
+ - **CVE-2026-2581** (MODERATE): Unbounded memory consumption in deduplication handler
62
+
63
+ These are non-breaking security patches that harden undici against untrusted upstream endpoints and malicious WebSocket frames.
64
+
65
+ **Advisories**: GHSA-f269-vfmq-vjvj, GHSA-v9p9-hfj2-hcw8, GHSA-4992-7rv2-5pvq, GHSA-phc3-fgpg-7m6h
66
+ **Fixed in**: undici 7.24.0+ (deployed 7.24.3)
8
67
 
9
- - Updated dependencies [[`f647825`](https://github.com/equinor/fusion-framework/commit/f647825cb5712763b09dafda21fd996211c78b78)]:
10
- - @equinor/fusion-framework-react-module@3.1.15-next.0
11
- - @equinor/fusion-framework-module-navigation@7.0.0-next.2
12
- - @equinor/fusion-framework-react-module-http@10.0.2-next.0
13
- - @equinor/fusion-framework-react@7.4.21-next.0
14
- - @equinor/fusion-framework-module-app@7.4.2-next.0
15
- - @equinor/fusion-framework-app@10.4.10-next.0
16
- - @equinor/fusion-framework-module-http@7.0.9-next.0
17
- - @equinor/fusion-framework-module@5.0.7-next.0
18
- - @equinor/fusion-framework-module-msal@7.3.2-next.0
68
+ - Updated dependencies [abffa53]
69
+ - Updated dependencies [abffa53]
70
+ - Updated dependencies [abffa53]
71
+ - Updated dependencies [abffa53]
72
+ - Updated dependencies [abffa53]
73
+ - Updated dependencies [abffa53]
74
+ - Updated dependencies [abffa53]
75
+ - Updated dependencies [abffa53]
76
+ - Updated dependencies [abffa53]
77
+ - Updated dependencies [aaa3f74]
78
+ - @equinor/fusion-framework-app@11.0.0
79
+ - @equinor/fusion-framework-module@6.0.0
80
+ - @equinor/fusion-framework-module-app@8.0.0
81
+ - @equinor/fusion-framework-module-http@8.0.0
82
+ - @equinor/fusion-framework-module-msal@8.0.0
83
+ - @equinor/fusion-framework-module-navigation@7.0.0
84
+ - @equinor/fusion-framework-react@8.0.0
85
+ - @equinor/fusion-framework-react-module@4.0.0
86
+ - @equinor/fusion-framework-react-module-http@11.0.0
19
87
 
20
88
  ## 9.0.8
21
89
 
package/README.md CHANGED
@@ -1,139 +1,216 @@
1
- # Fusion React App
1
+ # @equinor/fusion-framework-react-app
2
2
 
3
- Package for developing applications that uses the `@equinor/fusion-framework`.
3
+ React bindings for building modular Fusion Framework applications. Provides rendering helpers, configuration callbacks, and React hooks for accessing framework modules (HTTP, auth, context, navigation, bookmarks, settings, and more).
4
+
5
+ ## Features
6
+
7
+ - **One-line app bootstrap** via `renderApp` — creates a render function that mounts your component with React 18's `createRoot`
8
+ - **Module hooks** — `useAppModule` / `useAppModules` for type-safe access to any registered module
9
+ - **Sub-path entry-points** for optional capabilities: MSAL auth, HTTP, context, navigation, bookmarks, feature flags, settings, analytics, AG Grid theming, help center, and apploader
10
+ - **Environment variables** hook — `useAppEnvironmentVariables` for accessing app config at runtime
11
+ - **Lazy loading** — components are wrapped in `React.lazy` + `Suspense` automatically
12
+
13
+ ## Installation
14
+
15
+ ```sh
16
+ pnpm add @equinor/fusion-framework-react-app
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Bootstrap an application
4
22
 
5
- ## Configure
6
23
  ```tsx
7
24
  // config.ts
8
- import { AppConfigurator } from '@equinor/fusion-framework-react-app';
9
- const configCallback: AppConfigurator = (configurator) => {
10
- configurator.http.configureClient(
11
- 'bar', {
12
- baseUri: 'https://somewhere-test.com',
13
- defaultScopes: ['foo/.default']
14
- }
15
- );
25
+ import type { AppModuleInitiator } from '@equinor/fusion-framework-react-app';
26
+
27
+ export const configure: AppModuleInitiator = (configurator) => {
28
+ configurator.http.configureClient('my-api', {
29
+ baseUri: 'https://api.example.com',
30
+ defaultScopes: ['api://my-api/.default'],
31
+ });
16
32
  };
17
33
 
18
34
  // App.tsx
19
- export const App = () => {
20
- const client = useHttpClient('bar');
21
- const [foo, setFoo] = useState('no value');
22
- const onClick = useCallback(() => {
23
- client.fetchAsync('api').then(x => x.json).then(setFoo);
24
- }, [client]);
25
- return <Button onClick={onClick}>{foo}</Button>
26
- }
35
+ export const App = () => <h1>Hello Fusion</h1>;
27
36
 
28
37
  // index.ts
29
- import { createApp } from '@equinor/fusion-framework-react-app';
30
- export const render = createApp(App, configCallback);
38
+ import { renderApp } from '@equinor/fusion-framework-react-app';
39
+ import { App } from './App';
40
+ import { configure } from './config';
41
+
42
+ export const render = renderApp(App, configure);
31
43
  export default render;
32
44
  ```
33
45
 
34
- ## Hooks
46
+ ### Access a module
35
47
 
36
- ### useModule
37
48
  ```tsx
38
- import { useModule } from '@equinor/fusion-framework-react-app';
39
- const ShowToken = () => {
40
- const auth = useModule('auth');
41
- const [token, setToken] = useState<string>('');
42
- useEffect(() => {
43
- auth.acquireAccessToken().then(setToken);
44
- }, [auth]);
45
- return <span>{token ?? 'fetching token'}</span>
46
- }
49
+ import { useAppModule } from '@equinor/fusion-framework-react-app';
50
+
51
+ const MyComponent = () => {
52
+ const auth = useAppModule('auth');
53
+ // ...
54
+ };
47
55
  ```
48
56
 
49
- ## MSAL Authentication
57
+ ### HTTP requests
50
58
 
51
- > [!IMPORTANT]
52
- > `@equinor/fusion-framework-module-msal` must be installed to make MSAL hooks available
59
+ ```tsx
60
+ import { useHttpClient } from '@equinor/fusion-framework-react-app/http';
53
61
 
54
- > [!CAUTION]
55
- > **Applications should NOT configure the MSAL module themselves.** The MSAL module must be configured by the host/portal application for proper module hoisting. Apps should only use the hooks to access the already-configured MSAL module.
62
+ const MyComponent = () => {
63
+ const client = useHttpClient('my-api');
64
+ // client.fetch$('endpoint').subscribe(...)
65
+ // await client.fetchAsync('endpoint')
66
+ };
67
+ ```
56
68
 
57
- This package includes React hooks for Microsoft authentication using MSAL v4.
69
+ ### MSAL authentication
58
70
 
59
- ```tsx
60
- import { useCurrentAccount, useAccessToken, useToken } from '@equinor/fusion-framework-react-app/msal';
71
+ > **Note:** Requires `@equinor/fusion-framework-module-msal`. The MSAL module must be configured by the host/portal — apps should only consume the hooks.
61
72
 
62
- const scopes = ['User.Read', 'api.read'];
73
+ ```tsx
74
+ import { useCurrentAccount, useAccessToken } from '@equinor/fusion-framework-react-app/msal';
63
75
 
64
- function MyComponent() {
65
- // Get current logged-in user
76
+ const UserInfo = () => {
66
77
  const user = useCurrentAccount();
67
-
68
- // Get access token for API calls
69
- const { token: accessToken } = useAccessToken( { scopes } );
70
-
71
- // Get full token details
72
- const { token } = useToken( { scopes } );
73
-
74
- if (!user) return <div>Please log in</div>;
75
- return <div>Welcome, {user.name}!</div>;
76
- }
78
+ const { token } = useAccessToken({ scopes: ['User.Read'] });
79
+ if (!user) return <p>Not signed in</p>;
80
+ return <p>Welcome, {user.name}</p>;
81
+ };
77
82
  ```
78
83
 
79
- 📖 **[See MSAL Authentication Documentation](docs/msal.md) for complete API reference, examples, and migration guide.**
84
+ ### Context
80
85
 
81
- ## Http
86
+ ```tsx
87
+ import { useCurrentContext } from '@equinor/fusion-framework-react-app/context';
88
+
89
+ const ContextInfo = () => {
90
+ const context = useCurrentContext();
91
+ return <p>Selected: {context?.title ?? 'none'}</p>;
92
+ };
93
+ ```
82
94
 
83
- ### useHttpClient
95
+ ### Navigation / routing
84
96
 
85
97
  ```tsx
86
- import { useHttpClient } from '@equinor/fusion-framework-react-app/http';
98
+ import { useRouter } from '@equinor/fusion-framework-react-app/navigation';
99
+ import { RouterProvider } from '@equinor/fusion-framework-react-router';
100
+
101
+ const routes = [{ path: '/', element: <Home /> }];
102
+
87
103
  const App = () => {
88
- const fooClient = useHttpClient('foo');
89
-
90
- // using as stream
91
- useEffect(() => {
92
- const sub = client.fetch('api/all').subscribe((x) => {
93
- setFoo(x.json());
94
- });
95
- return () => sub.unsubscribe();
96
- },[fooClient]);
97
-
98
- // using as promise
99
- const barClient = useHttpClient('bar');
100
- useCallback(async() => {
101
- const res = await portalClient.fetchAsync('api/bar');
102
- console.log(res.json());
103
- },[barClient]);
104
-
105
- }
104
+ const router = useRouter(routes);
105
+ return <RouterProvider router={router} />;
106
+ };
106
107
  ```
107
108
 
108
- ## Feature Flag
109
+ ### Feature flags
109
110
 
110
- > [!IMPORTANT]
111
- > `@equinor/fusion-framework-module-feature-flag` must be installed to make this module available
111
+ > **Note:** Requires `@equinor/fusion-framework-module-feature-flag`.
112
112
 
113
- ### Simple
114
- ```ts
115
- import { enableFeatureFlag } from '@equinor/fusion-framework-react-app/feature-flag';
116
- export const configure: ModuleInitiator = (appConfigurator, args) => {
117
- /** provide a list of features that should be available in the application */
118
- enableFeatureFlag(appConfigurator, [
119
- {
120
- key: MyFeatures.MyFlag,
121
- title: 'this is a flag',
122
- },
123
- {
124
- key: MyFeatures.MyUrlFlag,
125
- title: 'this feature can be toggled by ?my-url-flag=true',
126
- allowUrl: true,
127
- }
113
+ ```tsx
114
+ import { enableFeatureFlag } from '@equinor/fusion-framework-react-app/feature-flag';
115
+
116
+ export const configure: AppModuleInitiator = (configurator) => {
117
+ enableFeatureFlag(configurator, [
118
+ { key: 'dark-mode', title: 'Dark mode' },
119
+ { key: 'beta-ui', title: 'Beta UI', allowUrl: true },
128
120
  ]);
129
- }
121
+ };
122
+ ```
123
+
124
+ ```tsx
125
+ import { useFeature } from '@equinor/fusion-framework-react-app/feature-flag';
126
+
127
+ const Toggle = () => {
128
+ const { feature, toggleFeature } = useFeature('dark-mode');
129
+ return <Switch checked={feature?.enabled} onChange={() => toggleFeature()} />;
130
+ };
131
+ ```
132
+
133
+ ### Bookmarks
134
+
135
+ ```tsx
136
+ import { useCurrentBookmark } from '@equinor/fusion-framework-react-app/bookmark';
137
+
138
+ const BookmarkView = () => {
139
+ const { currentBookmark } = useCurrentBookmark();
140
+ return <pre>{JSON.stringify(currentBookmark, null, 2)}</pre>;
141
+ };
142
+ ```
143
+
144
+ ### Settings
145
+
146
+ ```tsx
147
+ import { useAppSetting } from '@equinor/fusion-framework-react-app/settings';
148
+
149
+ const ThemePicker = () => {
150
+ const [theme, setTheme] = useAppSetting('theme', 'light');
151
+ return <button onClick={() => setTheme('dark')}>Go dark</button>;
152
+ };
153
+ ```
154
+
155
+ ### Environment variables
156
+
157
+ ```tsx
158
+ import { useAppEnvironmentVariables } from '@equinor/fusion-framework-react-app';
159
+
160
+ const EnvInfo = () => {
161
+ const env = useAppEnvironmentVariables();
162
+ if (!env.complete) return <p>Loading…</p>;
163
+ return <pre>{JSON.stringify(env.value, null, 2)}</pre>;
164
+ };
130
165
  ```
131
166
 
132
- ### Custom
167
+ ## API Reference
168
+
169
+ ### Core exports (main entry-point)
170
+
171
+ | Export | Description |
172
+ | --- | --- |
173
+ | `renderApp` | Creates a mount function from a component and optional config callback |
174
+ | `makeComponent` | Lazily initialises modules and wraps a component in framework providers |
175
+ | `createComponent` | _(deprecated)_ Factory returning a `ComponentRenderer` |
176
+ | `createLegacyApp` | _(deprecated)_ Wrapper for legacy Fusion CLI apps |
177
+ | `renderComponent` | Lower-level helper: mounts a `ComponentRenderer` via `createRoot` |
178
+ | `useAppModule(key)` | Returns a single module instance by key |
179
+ | `useAppModules()` | Returns all initialised application modules |
180
+ | `useAppEnvironmentVariables()` | Observable state of the app's environment config |
181
+
182
+ ### Sub-path entry-points
183
+
184
+ | Path | Key exports |
185
+ | --- | --- |
186
+ | `/msal` | `useCurrentAccount`, `useAccessToken`, `useToken` |
187
+ | `/http` | `useHttpClient` (re-export) |
188
+ | `/http/selectors` | Response selector utilities |
189
+ | `/context` | `useCurrentContext`, `useContextProvider`, `useFrameworkCurrentContext` |
190
+ | `/navigation` | `useRouter`, `useNavigationModule` |
191
+ | `/feature-flag` | `enableFeatureFlag`, `useFeature` |
192
+ | `/bookmark` | `enableBookmark`, `useCurrentBookmark`, `useBookmark` |
193
+ | `/settings` | `useAppSetting`, `useAppSettings` |
194
+ | `/analytics` | `useTrackFeature` |
195
+ | `/help-center` | `useHelpCenter` |
196
+ | `/apploader` | `Apploader`, `useApploader` |
197
+ | `/framework` | `useFramework`, `useCurrentUser`, `useFrameworkHttpClient` |
198
+ | `/widget` | Widget entry-point |
199
+
200
+ ## Configuration
201
+
202
+ Application configuration is done via a callback passed to `renderApp` (or `makeComponent`). The callback receives an `IAppConfigurator` with builders for each module:
203
+
133
204
  ```ts
134
- export const configure: ModuleInitiator = (appConfigurator, args) => {
135
- appConfigurator.useFeatureFlags(builder => /** see module for building custom config */);
136
- }
205
+ const configure: AppModuleInitiator = (configurator) => {
206
+ // HTTP clients
207
+ configurator.http.configureClient('my-api', { baseUri: '...' });
208
+
209
+ // Feature flags
210
+ enableFeatureFlag(configurator, [{ key: 'beta', title: 'Beta' }]);
211
+
212
+ // Navigation, context, etc. — see module docs
213
+ };
137
214
  ```
138
215
 
139
- [see module](https://equinor.github.io/fusion-framework/modules/feature-flag/module.html) for more technical information;
216
+ > The MSAL / auth module is configured by the host portal and hoisted to apps automatically. Do **not** configure it in application code.
@@ -1,4 +1,11 @@
1
1
  import { useAppModule } from '../useAppModule';
2
+ /**
3
+ * React hook that returns the current AG Grid theme from the application-scoped
4
+ * AG Grid module.
5
+ *
6
+ * @returns The active {@link Theme} object.
7
+ * @throws If the AG Grid module is not registered in the application.
8
+ */
2
9
  export const useTheme = () => {
3
10
  const agGrid = useAppModule('agGrid');
4
11
  if (!agGrid) {
@@ -1 +1 @@
1
- {"version":3,"file":"useTheme.js","sourceRoot":"","sources":["../../../src/ag-grid/useTheme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAI/C,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAU,EAAE;IAClC,MAAM,MAAM,GAAG,YAAY,CAAe,QAAQ,CAAC,CAAC;IAEpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,MAAM,CAAC,KAAc,CAAC;AAC/B,CAAC,CAAC"}
1
+ {"version":3,"file":"useTheme.js","sourceRoot":"","sources":["../../../src/ag-grid/useTheme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAI/C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAU,EAAE;IAClC,MAAM,MAAM,GAAG,YAAY,CAAe,QAAQ,CAAC,CAAC;IAEpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,MAAM,CAAC,KAAc,CAAC;AAC/B,CAAC,CAAC"}
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Analytics sub-path entry-point.
3
+ *
4
+ * Provides the {@link useTrackFeature} hook for tracking application-level
5
+ * analytics events through the Fusion analytics module.
6
+ *
7
+ * @packageDocumentation
8
+ */
1
9
  export { useTrackFeature } from './useTrackFeature';
2
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,7 +1,23 @@
1
1
  import { useFrameworkModule } from '@equinor/fusion-framework-react';
2
2
  import { useCallback } from 'react';
3
3
  /**
4
- * Hook for using analytics module configured in the framework.
4
+ * React hook that returns a callback for tracking application feature usage
5
+ * via the Fusion analytics module.
6
+ *
7
+ * The tracked event includes the current app key and context (if available)
8
+ * as attributes, enabling downstream analytics dashboards to group events
9
+ * by application and context.
10
+ *
11
+ * @returns A `trackFeature` callback: `(name: string, data?: AnyValueMap) => void`.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const trackFeature = useTrackFeature();
16
+ *
17
+ * const handleClick = useCallback(() => {
18
+ * trackFeature('button-click', { section: 'header' });
19
+ * }, [trackFeature]);
20
+ * ```
5
21
  */
6
22
  export const useTrackFeature = () => {
7
23
  const analyticsProvider = useFrameworkModule('analytics');
@@ -1 +1 @@
1
- {"version":3,"file":"useTrackFeature.js","sourceRoot":"","sources":["../../../src/analytics/useTrackFeature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,MAAM,iBAAiB,GAAG,kBAAkB,CAAkB,WAAW,CAAC,CAAC;IAC3E,MAAM,WAAW,GAAG,kBAAkB,CAAY,KAAK,CAAC,CAAC;IACzD,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAE1D;;;;;;;OAOG;IACH,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAAY,EAAE,IAAkB,EAAE,EAAE;QACnC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,iBAAiB,EAAE,cAAc,CAAC;gBAChC,IAAI,EAAE,2BAA2B;gBACjC,SAAS,EAAE,IAAI,KAAK,CAAC,8BAA8B,CAAC;aACrD,CAAC,CAAC;QACL,CAAC;QAED,iBAAiB,EAAE,aAAa,CAAC;YAC/B,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI;aACL;YACD,UAAU,EAAE;gBACV,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM;gBACpC,OAAO,EAAE,eAAe,EAAE,cAAc;oBACtC,CAAC,CAAC;wBACE,EAAE,EAAE,eAAe,CAAC,cAAc,CAAC,EAAE;wBACrC,UAAU,EAAE,eAAe,CAAC,cAAc,CAAC,UAAU;wBACrD,KAAK,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK;wBAC3C,IAAI,EAAE,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;wBAC5C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,MAAM;qBAC9C;oBACH,CAAC,CAAC,SAAS;aACd;SACF,CAAC,CAAC;IACL,CAAC,EACD,CAAC,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,CAAC,CACrE,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
1
+ {"version":3,"file":"useTrackFeature.js","sourceRoot":"","sources":["../../../src/analytics/useTrackFeature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,MAAM,iBAAiB,GAAG,kBAAkB,CAAkB,WAAW,CAAC,CAAC;IAC3E,MAAM,WAAW,GAAG,kBAAkB,CAAY,KAAK,CAAC,CAAC;IACzD,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAE1D;;;;;;;OAOG;IACH,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAAY,EAAE,IAAkB,EAAE,EAAE;QACnC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,iBAAiB,EAAE,cAAc,CAAC;gBAChC,IAAI,EAAE,2BAA2B;gBACjC,SAAS,EAAE,IAAI,KAAK,CAAC,8BAA8B,CAAC;aACrD,CAAC,CAAC;QACL,CAAC;QAED,iBAAiB,EAAE,aAAa,CAAC;YAC/B,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI;aACL;YACD,UAAU,EAAE;gBACV,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM;gBACpC,OAAO,EAAE,eAAe,EAAE,cAAc;oBACtC,CAAC,CAAC;wBACE,EAAE,EAAE,eAAe,CAAC,cAAc,CAAC,EAAE;wBACrC,UAAU,EAAE,eAAe,CAAC,cAAc,CAAC,UAAU;wBACrD,KAAK,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK;wBAC3C,IAAI,EAAE,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;wBAC5C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,MAAM;qBAC9C;oBACH,CAAC,CAAC,SAAS;aACd;SACF,CAAC,CAAC;IACL,CAAC,EACD,CAAC,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,CAAC,CACrE,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Apploader sub-path entry-point.
3
+ *
4
+ * Provides the {@link Apploader} component and {@link useApploader} hook
5
+ * for embedding Fusion child applications inside a parent Fusion application.
6
+ *
7
+ * @packageDocumentation
8
+ */
1
9
  export { Apploader } from './Apploader';
2
10
  export { useApploader } from './useApploader';
3
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/apploader/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/apploader/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAuB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Bookmark sub-path entry-point.
3
+ *
4
+ * Provides helpers to enable and consume the Fusion bookmark module,
5
+ * allowing users to save and restore application state snapshots.
6
+ *
7
+ * @packageDocumentation
8
+ */
1
9
  export { enableBookmark } from '@equinor/fusion-framework-app/enable-bookmark';
2
10
  export { useCurrentBookmark } from './useCurrentBookmark';
3
11
  export { useBookmark } from './useBookmark';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bookmark/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bookmark/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Context sub-path entry-point.
3
+ *
4
+ * Provides hooks for reading and interacting with the Fusion context
5
+ * (project, facility, etc.) at both the application and framework level.
6
+ *
7
+ * @packageDocumentation
8
+ */
1
9
  export * from '@equinor/fusion-framework-react-module-context';
2
10
  export { useContextProvider } from './useContextProvider';
3
11
  export { useCurrentContext } from './useCurrentContext';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/context/index.ts"],"names":[],"mappings":"AAAA,cAAc,gDAAgD,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/context/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,gDAAgD,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC"}
@@ -1,4 +1,10 @@
1
1
  import { useAppModule } from '../useAppModule';
2
+ /**
3
+ * React hook that resolves the application-scoped context module provider.
4
+ *
5
+ * @returns The context module provider instance.
6
+ * @throws If the context module is not registered in the application scope.
7
+ */
2
8
  export const useContextProvider = () => useAppModule('context');
3
9
  export default useContextProvider;
4
10
  //# sourceMappingURL=useContextProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useContextProvider.js","sourceRoot":"","sources":["../../../src/context/useContextProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAgB,SAAS,CAAC,CAAC;AAE/E,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"useContextProvider.js","sourceRoot":"","sources":["../../../src/context/useContextProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAgB,SAAS,CAAC,CAAC;AAE/E,eAAe,kBAAkB,CAAC"}
@@ -1,5 +1,19 @@
1
1
  import { useCurrentContext as _useCurrentContext } from '@equinor/fusion-framework-react-module-context';
2
2
  import useContextProvider from './useContextProvider';
3
+ /**
4
+ * React hook that returns the currently selected Fusion context from the
5
+ * **application-scoped** context module.
6
+ *
7
+ * @returns The current context object, or `undefined` if no context is selected.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const context = useCurrentContext();
12
+ * if (context) {
13
+ * console.log('Selected:', context.title);
14
+ * }
15
+ * ```
16
+ */
3
17
  export const useCurrentContext = () => _useCurrentContext(useContextProvider());
4
18
  export default useCurrentContext;
5
19
  //# sourceMappingURL=useCurrentContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCurrentContext.js","sourceRoot":"","sources":["../../../src/context/useCurrentContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,IAAI,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACzG,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAEtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEhF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"useCurrentContext.js","sourceRoot":"","sources":["../../../src/context/useCurrentContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,IAAI,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACzG,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEhF,eAAe,iBAAiB,CAAC"}
@@ -2,6 +2,19 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Suspense, useMemo } from 'react';
3
3
  import { useFramework } from '@equinor/fusion-framework-react';
4
4
  import { createComponent } from './create-component';
5
+ /**
6
+ * Creates a legacy wrapper component that bootstraps a Fusion React app within
7
+ * the older Fusion CLI hosting model.
8
+ *
9
+ * @deprecated Prefer {@link renderApp} for new applications. This helper exists
10
+ * only for backward-compatibility with apps that must run inside the legacy
11
+ * Fusion CLI.
12
+ *
13
+ * @template TModules - Array of additional module types to initialise.
14
+ * @param Component - The root React element to render.
15
+ * @param configure - Optional callback to configure application modules.
16
+ * @returns A React function component that initialises modules and renders the app.
17
+ */
5
18
  export const createLegacyApp = (Component, configure) => {
6
19
  const LegacyComponent = () => {
7
20
  const fusion = useFramework();
@@ -1 +1 @@
1
- {"version":3,"file":"create-legacy-app.js","sourceRoot":"","sources":["../../src/create-legacy-app.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAoB,MAAM,OAAO,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAK/D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,SAAsB,EACtB,SAAwC,EACxC,EAAE;IACF,MAAM,eAAe,GAAG,GAAG,EAAE;QAC3B,MAAM,MAAM,GAAG,YAAY,EAAe,CAAC;QAC3C,qFAAqF;QACrF,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;YACnC,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACtD,YAAY;YACZ,oDAAoD;YACpD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;YACvC,IAAI,WAAW,EAAE,OAAO,EAAE,CAAC;gBACzB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;gBACjD,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAuB,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,OAAO,CAAC,MAAM,EAAE,EAAuB,CAAC,CAAC;QAClD,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACb,OAAO,CACL,KAAC,QAAQ,IAAC,QAAQ,EAAE,sCAAkB,YACpC,KAAC,eAAe,KAAG,GACV,CACZ,CAAC;IACJ,CAAC,CAAC;IACF,OAAO,eAAe,CAAC;AACzB,CAAC,CAAC"}
1
+ {"version":3,"file":"create-legacy-app.js","sourceRoot":"","sources":["../../src/create-legacy-app.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAoB,MAAM,OAAO,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAK/D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,SAAsB,EACtB,SAAwC,EACxC,EAAE;IACF,MAAM,eAAe,GAAG,GAAG,EAAE;QAC3B,MAAM,MAAM,GAAG,YAAY,EAAe,CAAC;QAC3C,qFAAqF;QACrF,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;YACnC,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACtD,YAAY;YACZ,oDAAoD;YACpD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;YACvC,IAAI,WAAW,EAAE,OAAO,EAAE,CAAC;gBACzB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;gBACjD,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAuB,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,OAAO,CAAC,MAAM,EAAE,EAAuB,CAAC,CAAC;QAClD,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACb,OAAO,CACL,KAAC,QAAQ,IAAC,QAAQ,EAAE,sCAAkB,YACpC,KAAC,eAAe,KAAG,GACV,CACZ,CAAC;IACJ,CAAC,CAAC;IACF,OAAO,eAAe,CAAC;AACzB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/feature-flag/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/feature-flag/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -5,10 +5,26 @@ import { useObservableState } from '@equinor/fusion-observable/react';
5
5
  import { findFeature } from '@equinor/fusion-framework-module-feature-flag/selectors';
6
6
  import { useAppModule } from '../useAppModule';
7
7
  /**
8
- * Custom hook for accessing and manipulating feature flags.
9
- * @template T - The type of the feature flag value.
10
- * @param key - The key of the feature flag.
11
- * @returns An object containing the feature flag, toggle function, and error (if any).
8
+ * React hook for reading and toggling a single feature flag.
9
+ *
10
+ * Merges feature flags from both the framework and the application scope,
11
+ * so framework-level flags are visible alongside app-specific ones.
12
+ *
13
+ * @template T - The type of the feature flag's value payload.
14
+ * @param key - The unique key identifying the feature flag.
15
+ * @returns An object with:
16
+ * - `feature` – the resolved {@link IFeatureFlag}, or `undefined` if not found.
17
+ * - `toggleFeature` – callback to toggle the flag; pass `true`/`false` to
18
+ * set explicitly, or omit to invert the current state.
19
+ * - `error` – any error from the feature-flag observable.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * const { feature, toggleFeature } = useFeature('dark-mode');
24
+ * return (
25
+ * <Switch checked={feature?.enabled} onChange={() => toggleFeature()} />
26
+ * );
27
+ * ```
12
28
  */
13
29
  export const useFeature = (key) => {
14
30
  const appProvider = useAppModule('featureFlag');