Login
Login components include React components, context and hooks for handling user authorisation, api tokens, session polling and GraphQL queries.
Creating and connecting your own module
If there is a need for a deeper connection to other modules, a custom module can be created. Modules can emit signals. Modules are not React-specific, just plain javascript. A module passed to the Beacon must have the following properties:
Property | Description |
---|---|
connect(beacon) | Function called when a module is added to the Beacon . |
namespace | String. A unique namespace. |
import { createNamespacedBeacon, ConnectedModule } from 'hds-react';const createMyCustomModule = (): ConnectedModule => {const customBeacon = createNamespacedBeacon('myModule');const listener = (signal) => {// This is listenening everything};return {namespace: helperNamespace,connect: (targetBeacon) => {customBeacon.storeBeacon(targetBeacon);customBeacon.addListener(createTriggerForAllSignalTypes(), listener);},};};
Connecting your module
Modules are automatically connected to other modules when they are passed in the modules
property of the LoginProvider.
Module.connect()
is called and when all modules are connected, an init
signal is emitted for each module. This is done by the Beacon
.
import { createNamespacedBeacon, ConnectedModule } from 'hds-react';const myModule = createMyCustomModule()const providerProperties = {..., modules=[myModule]}<LoginProvider {...providerProperties}><Content /></LoginProvider>
Custom namespaced beacons for modules
Modules must emit signals in their namespace. Beacon has only one emit function. To make emitting easier, the createNamespacedBeacon
returns a utility where all emitted signals have a pre-set namespace and there are emit functions for different signal types.
This utility also handles cases where listeners are added before the module is connected to the Beacon
.
It also ignores signals from its namespace when listening to generic signals.
Name | Description | Return values |
---|---|---|
addListener(signalProps, listener) | Adds a listener for given signal props. Module's own signals are filtered out if the namespace is for all signals. | A disposer function |
emit(signal) | Calls the beacon.emit , if the Beacon is connected. | none |
emitError(payload) | Emits an error with the given payload. | Context module or undefined |
emitEvent(payload, data) | Emits an event with the given type and data in the payload. | Object |
emitStateChange(state,previousState) | Emits a stateChange with the given state and previousState in the payload. | none |
storeBeacon(beacon) | Beacon . Call this from the module.connect() . Stores the beacon, so the module does not have to store it. | none |
import { createNamespacedBeacon, ConnectedModule } from 'hds-react';const createMyCustomModule = (): ConnectedModule => {let state = 'none';const customBeacon = createNamespacedBeacon('myModule');const listener = (signal) => {if (isErrorSignal) {newState = 'error';customBeacon.emitStateChange(newState, state);state = newState;}};return {namespace: helperNamespace,connect: (targetBeacon) => {customBeacon.storeBeacon(targetBeacon);customBeacon.addListener(createTriggerForAllSignalTypes(), listener);},};};
Emitting signals
The following example is for custom modules because components cannot emit signals.
// Beacon is not imported, this example assumes it is in the scopeconst error = new OidcClientError('Failed', oidcClientError.SIGNIN_ERROR),// This is the same asbeacon.emit({type: errorSignalType,namespace: 'teamHDS',payload: error,});// Thisbeacon.emit(createErrorSignal('teamHDS', error));// and this - if custom, namespaced beacon is created for 'teamHDS'customBeacon.emitError(error);
Listening to signals
A signal listener is a function that receives one argument: the signal. A listener can listen to all signals or just one type of signal with a certain namespace. Listeners can be even more specific and listen to signals with certain payloads. In short, a listener can listen to any properties of the signal and is triggered when all properties match.
The listener is called only if the emitted signal matches the given props.
For example, if the trigger props (the first argument) passed to beacon.addListener(trigger, listener)
is { type:'error' }
, the listener (second argument) is called when the emitted signal has a matching type. It does not matter what other props the signal has.
If the trigger props are { namespace:'myModule', payload:{type:'click'} }
, the emitted signal must have those properties with the same, exact values. Other properties are not checked.
The trigger can also be a function. Internally all triggers are converted to functions.
const listener = (signal) => {// Do something with the signal.};// Listen to all error signalsconst trigger = { type: 'error' };const disposer = beacon.addListener(trigger, listener);// The listener can be removed by calling the returned disposerdisposer();