@selfcommunity/react-core
Version:
React Core Components useful for integrating UI Community components (react-ui).
114 lines (110 loc) • 5.45 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useMemo } from 'react';
import { useSCContext } from '../SCContextProvider';
import { SCPreferencesContext } from '../SCPreferencesProvider';
import * as SCPreferences from '../../../constants/Preferences';
import { CATEGORIES_LIST_ROUTE_NAME, CATEGORY_ROUTE_NAME, COMMENT_ROUTE_NAME, DISCUSSION_ROUTE_NAME, INCUBATOR_ROUTE_NAME, POST_ROUTE_NAME, STATUS_ROUTE_NAME, USER_NOTIFICATIONS_ROUTE_NAME, USER_PRIVATE_MESSAGES_ROUTE_NAME, USER_PROFILE_ROUTE_NAME, USER_PROFILE_SETTINGS_ROUTE_NAME, defaultRoutes, LIVESTREAM_ROUTE_NAME, } from '../../../constants/Routes';
/**
* Creates Global Context
*
:::tip Context can be consumed in one of the following ways:
```jsx
1. <SCRoutingContext.Consumer>{(routerLink, routes, url) => (...)}</SCRoutingContext.Consumer>
```
```jsx
2. const scRoutingContext: SCRoutingContextType = useContext(SCRoutingContext);
```
```jsx
3. const scRoutingContext: SCRoutingContextType = useSCRouting();
````
:::
*/
export const SCRoutingContext = createContext({});
/**
* #### Description:
* This component provides routing context.
* @param children
* @return
* ```jsx
* <SCRoutingContext.Provider value={contextValue}>{children}</SCRoutingContext.Provider>
* ```
*/
export default function SCRoutingProvider({ children = null }) {
const scPreferencesContext = useContext(SCPreferencesContext);
const scContext = useSCContext();
const router = scContext.settings.router ? scContext.settings.router : {};
const routerLink = router.routerLink ? router.routerLink : null;
const _routes = Object.assign(getPreferencesRoutes(), defaultRoutes);
const routes = router.routes ? Object.assign(Object.assign({}, _routes), router.routes) : defaultRoutes;
/**
* Normalize template url (preferences)
*/
function normalizeUrl(url) {
let tpl = url;
const re = /\{([^/]+)?\}/g;
let match = re.exec(url);
while (match) {
tpl = tpl.replace(match[0], `:${match[1]}`);
re.lastIndex = 0;
match = re.exec(tpl);
}
return tpl;
}
/**
* Get override routes from community preferences
*/
function getPreferencesRoutes() {
if (Object.keys(scPreferencesContext.preferences).length) {
return {
[POST_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_POST].value),
[DISCUSSION_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_DISCUSSION].value),
[STATUS_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_STATUS].value),
[COMMENT_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_COMMENT].value),
[CATEGORY_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_CATEGORY].value),
[CATEGORIES_LIST_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_CATEGORIES_LIST].value),
[USER_PROFILE_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_USER_PROFILE].value),
[USER_PROFILE_SETTINGS_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_USER_PROFILE_SETTINGS].value),
[USER_NOTIFICATIONS_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_NOTIFICATIONS].value),
[USER_PRIVATE_MESSAGES_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_USER_PRIVATE_MESSAGES].value),
[INCUBATOR_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_INCUBATOR].value),
[LIVESTREAM_ROUTE_NAME]: normalizeUrl(scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_URL_TEMPLATE_LIVE_STREAM].value),
};
}
return {};
}
/**
* Generate path
*/
function url(name = '', params = {}) {
const replacer = (tpl, data) => {
const re = /:([^/|^?|^#]+)?/g;
let _tpl = tpl;
let match = re.exec(tpl);
const hasParams = Object.keys(data).length > 0;
while (match) {
_tpl = hasParams ? _tpl.replace(match[0], data[match[1]]) : _tpl.split(match[0])[0];
re.lastIndex = 0;
match = re.exec(_tpl);
}
if (router.handleRoute) {
// Handle override url
return router.handleRoute(name, _tpl, params, tpl);
}
return _tpl;
};
return replacer(routes[name], params);
}
const contextValue = useMemo(() => ({
routerLink,
routes,
url,
}), [routerLink, routes]);
return _jsx(SCRoutingContext.Provider, Object.assign({ value: contextValue }, { children: children }));
}
/**
* Let's only export the `useSCTheme` hook instead of the context.
* We only want to use the hook directly and never the context component.
*/
export function useSCRouting() {
return useContext(SCRoutingContext);
}