@selfcommunity/react-core
Version:
React Core Components useful for integrating UI Community components (react-ui).
95 lines (94 loc) • 2.88 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useMemo, useState } from 'react';
import { http } from '@selfcommunity/api-services';
import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect';
import { validateOptions, validOptions } from '../../../utils/validator';
import useIsComponentMountedRef from '../../../utils/hooks/useIsComponentMountedRef';
/**
* Creates Global Context
*
:::tip Context can be consumed in one of the following ways:
```jsx
1. <SCContext.Consumer>{settings => (...)}</SCContext.Consumer>
```
```jsx
2. const scContext: SCContextType = useContext(SCContext);
```
```jsx
3. const scContext: SCContextType = useSCContext();
````
:::
*/
export const SCContext = createContext({});
/**
* This component imports all providers
* @param conf
* @param children
* @return
* ```jsx
* <SCContext.Provider value={{settings}}>
* ```
*/
export default function SCContextProvider({ conf, children }) {
/**
* Check initial conf and validates settings
* If the conf change update settings
*/
const _settings = useMemo(() => {
/**
* Validate initial settings
*/
const { validationResult, settings } = validateOptions(conf, validOptions);
if (validationResult.hasErrors()) {
/**
* Exist errors in initial conf
*/
validationResult.emit();
return null;
}
/**
* Emit warnings if exist
*/
validationResult.emitWarnings();
/**
* Set the base path on the http objects
*/
http.setBasePortal(settings.portal);
/**
* Render all Providers
*/
return settings;
}, [conf]);
/**
* Settings
*/
const [settings, setSettings] = useState(_settings);
/**
* Export the provider as we need to wrap the entire app with it
* This provider keeps current user logged and session
*/
useDeepCompareEffectNoCheck(() => {
if (!isMountedRef.current)
return;
setSettings(_settings);
}, [_settings]);
/**
* Track component initialization
*/
const isMountedRef = useIsComponentMountedRef();
/**
* Nesting all necessary providers
* All child components will use help contexts to works
*/
return (_jsx(SCContext.Provider, Object.assign({ value: { settings } }, { children: settings &&
settings.contextProviders.reduceRight((memo, ContextProvider) => {
return _jsx(ContextProvider, { children: memo });
}, children) })));
}
/**
* Let's only export the `useSCContext` hook instead of the context.
* We only want to use the hook directly and never the context component.
*/
export function useSCContext() {
return useContext(SCContext);
}