@gears-frontx/react 0.2.0-alpha.4 → 0.2.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -277,7 +277,9 @@ function MyExtension() {
277
277
 
278
278
  #### useSharedProperty
279
279
 
280
- Subscribe to shared property changes:
280
+ Subscribe to shared property changes. Two forms: the context form reads the bridge from `MfeContext`, and the options form accepts an explicit bridge and a fallback.
281
+
282
+ **Context form** — `useSharedProperty(propertyTypeId)`. Reads the bridge from `MfeContext` and throws if no `MfeProvider` is mounted. Returns the value (or `undefined` if the host has not published it), updating on every host publish.
281
283
 
282
284
  ```tsx
283
285
  import { useSharedProperty, Gears FrontX_SHARED_PROPERTY_THEME } from '@gears-frontx/react';
@@ -289,6 +291,31 @@ function ThemedComponent() {
289
291
  }
290
292
  ```
291
293
 
294
+ **Options form** — `useSharedProperty(propertyTypeId, { bridge, fallback })`. Use it for components that never mount `MfeProvider`, or to show a value until the host publishes one.
295
+
296
+ ```tsx
297
+ import { useSharedProperty } from '@gears-frontx/react';
298
+ import type { ChildMfeBridge } from '@gears-frontx/framework';
299
+
300
+ function StandaloneComponent({ bridge }: { bridge: ChildMfeBridge }) {
301
+ const label = useSharedProperty<string>(LABEL_PROPERTY_ID, {
302
+ bridge,
303
+ fallback: 'Untitled',
304
+ });
305
+
306
+ return <span>{label}</span>;
307
+ }
308
+ ```
309
+
310
+ `UseSharedPropertyOptions<T>` fields:
311
+
312
+ - `bridge` — bridge to read the property from, bypassing `MfeContext`. Pass it when the calling component never mounts `MfeProvider` (for example, a component that receives its bridge as a prop or from a non-React entry point). When omitted, the hook falls back to the bridge from `MfeContext` and throws if no `MfeProvider` is mounted. Changing `bridge` or `propertyTypeId` moves the subscription to the new source and the returned value follows on the same render.
313
+ - `fallback` — value returned while the host has not published the property yet. Only `undefined` is substituted; a published `null` is a real value and comes through as-is. With `fallback` set the hook returns `T` rather than `T | undefined`. It may be passed inline on every render without affecting the subscription.
314
+
315
+ There is no consumer-side validation option on purpose: the host validates every published value against the property's schema before it reaches any MFE (`TypeSystemPlugin.register()` throws on a mismatch and the update is never stored or delivered). `T` is the caller's declaration of that schema, as with `useState<T>`.
316
+
317
+ Both forms read through `useSyncExternalStore`, so the first render shows the host's current value and the result is tearing-protected under concurrent rendering. The TSDoc block on `useSharedProperty` in `src/mfe/hooks/useSharedProperty.ts` is the authoritative reference; this guide summarizes consumer-facing usage.
318
+
292
319
  #### useHostAction
293
320
 
294
321
  Invoke actions on the host application:
@@ -475,7 +502,7 @@ This allows users to import everything from `@gears-frontx/react` without needin
475
502
  - `useScreenTranslations` - Screen translation loading
476
503
  - `useTheme` - Theme utilities
477
504
  - `useMfeBridge` - Access MFE bridge
478
- - `useSharedProperty` - Subscribe to shared property
505
+ - `useSharedProperty` - Subscribe to shared property, via `MfeContext` or an explicit bridge
479
506
  - `useHostAction` - Invoke host action
480
507
  - `useDomainExtensions` - Subscribe to domain extensions
481
508
  - `useRegisteredPackages` - Subscribe to registered GTS packages
@@ -494,6 +521,7 @@ This allows users to import everything from `@gears-frontx/react` without needin
494
521
  - `QueryCache` - Restricted cache interface (accepts descriptors or raw keys)
495
522
  - `MutationCallbackContext` - Context with queryCache injected into mutation callbacks
496
523
  - `MfeProviderProps`, `ExtensionDomainSlotProps`
524
+ - `UseSharedPropertyOptions<T>` - Options for `useSharedProperty` (bridge, fallback)
497
525
  - `UseTranslationReturn`, `UseThemeReturn`
498
526
  - All types from @gears-frontx/framework (including `EndpointDescriptor`, `MutationDescriptor`, `StreamDescriptor`, `StreamStatus`)
499
527
 
package/dist/index.cjs CHANGED
@@ -1151,19 +1151,26 @@ function useMfeBridge() {
1151
1151
 
1152
1152
  // src/mfe/hooks/useSharedProperty.ts
1153
1153
  var import_react14 = require("react");
1154
- function useSharedProperty(propertyTypeId) {
1155
- const { bridge } = useMfeContext();
1156
- const subscribe = (0, import_react14.useCallback)((callback) => {
1157
- return bridge.subscribeToProperty(propertyTypeId, () => {
1158
- callback();
1159
- });
1160
- }, [bridge, propertyTypeId]);
1154
+ function useSharedProperty(propertyTypeId, options) {
1155
+ const contextValue = (0, import_react14.useContext)(MfeContext);
1156
+ const bridge = options?.bridge ?? contextValue?.bridge;
1157
+ const fallback = options?.fallback;
1158
+ if (!bridge) {
1159
+ throw new Error(
1160
+ "useSharedProperty must be used within a MfeProvider, or given an explicit `bridge` option, for components that never mount MfeProvider."
1161
+ );
1162
+ }
1163
+ const subscribe = (0, import_react14.useCallback)(
1164
+ (onStoreChange) => bridge.subscribeToProperty(propertyTypeId, () => {
1165
+ onStoreChange();
1166
+ }),
1167
+ [bridge, propertyTypeId]
1168
+ );
1161
1169
  const getSnapshot = (0, import_react14.useCallback)(() => {
1162
- const property = bridge.getProperty(propertyTypeId);
1163
- return property?.value;
1164
- }, [bridge, propertyTypeId]);
1165
- const value = (0, import_react14.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
1166
- return value;
1170
+ const raw = bridge.getProperty(propertyTypeId)?.value;
1171
+ return raw === void 0 ? fallback : raw;
1172
+ }, [bridge, propertyTypeId, fallback]);
1173
+ return (0, import_react14.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
1167
1174
  }
1168
1175
 
1169
1176
  // src/mfe/hooks/useHostAction.ts
@@ -1447,8 +1454,8 @@ var ThemeAwareReactLifecycle = class {
1447
1454
  line-height: 1.5;
1448
1455
  -webkit-font-smoothing: antialiased;
1449
1456
  -moz-osx-font-smoothing: grayscale;
1450
- color: hsl(var(--foreground));
1451
- background-color: hsl(var(--background));
1457
+ color: var(--foreground);
1458
+ background-color: var(--background);
1452
1459
  }
1453
1460
  `;
1454
1461
  const shellOwnedHead = container.querySelectorAll(