@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
155 lines (146 loc) • 13.7 kB
JavaScript
import { __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Avatar, Badge, Box, Button, IconButton, styled, Toolbar, Tooltip } from '@mui/material';
import React, { useMemo } from 'react';
import Icon from '@mui/material/Icon';
import { useThemeProps } from '@mui/system';
import classNames from 'classnames';
import NavigationToolbarSkeleton from './Skeleton';
import { FormattedMessage } from 'react-intl';
import NotificationMenu from './NotificationMenu';
import SearchAutocomplete from '../SearchAutocomplete';
import NavigationSettingsIconButton from '../NavigationSettingsIconButton';
import ComposerIconButton from '../ComposerIconButton';
import { SCFeatureName } from '@selfcommunity/types';
import { Link, SCPreferences, SCRoutes, UserUtils, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
import NavigationMenuIconButton from '../NavigationMenuIconButton';
import { PREFIX } from './constants';
const classes = {
root: `${PREFIX}-root`,
logo: `${PREFIX}-logo`,
customItem: `${PREFIX}-custom-item`,
register: `${PREFIX}-register`,
navigation: `${PREFIX}-navigation`,
home: `${PREFIX}-home`,
explore: `${PREFIX}-explore`,
events: `${PREFIX}-events`,
groups: `${PREFIX}-groups`,
search: `${PREFIX}-search`,
composer: `${PREFIX}-composer`,
profile: `${PREFIX}-profile`,
notification: `${PREFIX}-notification`,
notificationsMenu: `${PREFIX}-notifications-menu`,
messages: `${PREFIX}-messages`,
settings: `${PREFIX}-settings`,
active: `${PREFIX}-active`
};
const Root = styled(Toolbar, {
name: PREFIX,
slot: 'Root'
})(() => ({}));
const PREFERENCES = [
SCPreferences.CONFIGURATIONS_EXPLORE_STREAM_ENABLED,
SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY,
SCPreferences.LOGO_NAVBAR_LOGO,
SCPreferences.ADDONS_CLOSED_COMMUNITY,
SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_ENABLED,
SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL,
SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE,
SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT
];
/**
* > API documentation for the Community-JS NavigationToolbar component. Learn about the available props and the CSS API.
*
*
* This component renders the application header.
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/NavigationToolbar)
#### Import
```jsx
import {NavigationToolbar} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCNavigationToolbar` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCNavigationToolbar-root|Styles applied to the root element.|
|logo|.SCNavigationToolbar-logo|Styles applied to the logo element.|
|register|.SCNavigationToolbar-register|Styles applied to the register button elements.|
|navigation|.SCNavigationToolbar-navigation|Styles applied to the navigation container element|
|home|.SCNavigationToolbar-home|Styles applied to the home button|
|explore|.SCNavigationToolbar-explore|Styles applied to the explore button|
|groups|.SCNavigationToolbar-groups|Styles applied to the group button|
|events|.SCNavigationToolbar-events|Styles applied to the event button|
|search|.SCNavigationToolbar-search|Styles applied to the search component|
|composer|.SCNavigationToolbar-composer|Styles applied to the composer component|
|profile|.SCNavigationToolbar-profile|Styles applied to the profile button|
|notification|.SCNavigationToolbar-notification|Styles applied to the notification button|
|notificationsMenu|.SCNavigationToolbar-notifications-menu|Styles applied to the notifications menu|
|messages|.SCNavigationToolbar-messages|Styles applied to the messages button|
|settings|.SCNavigationToolbar-settings|Styles applied to the settings button|
|active|.SCNavigationToolbar-active|Styles applied to the active button on navigation|
*
* @param inProps
*/
export default function NavigationToolbar(inProps) {
// PROPS
const props = useThemeProps({
props: inProps,
name: PREFIX
});
const { value = '', className = '', disableSearch = false, disableComposer = false, SearchAutocompleteComponentProps = {}, startActions = null, endActions = null, NavigationSettingsIconButtonComponent = NavigationSettingsIconButton, NavigationMenuIconButtonComponentProps = {}, NavigationMenuIconButtonComponent = NavigationMenuIconButton, children = null, NotificationMenuProps = {}, ComposerIconButtonProps = {}, onOpenNotificationMenu, onCloseNotificationMenu } = props, rest = __rest(props, ["value", "className", "disableSearch", "disableComposer", "SearchAutocompleteComponentProps", "startActions", "endActions", "NavigationSettingsIconButtonComponent", "NavigationMenuIconButtonComponentProps", "NavigationMenuIconButtonComponent", "children", "NotificationMenuProps", "ComposerIconButtonProps", "onOpenNotificationMenu", "onCloseNotificationMenu"]);
// CONTEXT
const scUserContext = useSCUser();
const scRoutingContext = useSCRouting();
// PREFERENCES
const scPreferences = useSCPreferences();
const preferences = useMemo(() => {
const _preferences = {};
PREFERENCES.map((p) => (_preferences[p] = p in scPreferences.preferences ? scPreferences.preferences[p].value : null));
return _preferences;
}, [scPreferences.preferences]);
const privateMessagingEnabled = useMemo(() => scPreferences.features.includes(SCFeatureName.PRIVATE_MESSAGING), [scPreferences.features]);
const groupsEnabled = useMemo(() => scPreferences.preferences &&
scPreferences.features &&
scPreferences.features.includes(SCFeatureName.TAGGING) &&
scPreferences.features.includes(SCFeatureName.GROUPING) &&
SCPreferences.CONFIGURATIONS_GROUPS_ENABLED in scPreferences.preferences &&
scPreferences.preferences[SCPreferences.CONFIGURATIONS_GROUPS_ENABLED].value, [scPreferences.preferences, scPreferences.features]);
const eventsEnabled = useMemo(() => scPreferences.preferences &&
scPreferences.features &&
scPreferences.features.includes(SCFeatureName.TAGGING) &&
scPreferences.features.includes(SCFeatureName.EVENT) &&
SCPreferences.CONFIGURATIONS_EVENTS_ENABLED in scPreferences.preferences &&
scPreferences.preferences[SCPreferences.CONFIGURATIONS_EVENTS_ENABLED].value, [scPreferences.preferences, scPreferences.features]);
const showComposer = useMemo(() => {
return (!disableComposer &&
(!scPreferences.preferences[SCPreferences.CONFIGURATIONS_POST_ONLY_STAFF_ENABLED].value || UserUtils.isStaff(scUserContext.user)));
}, [preferences, disableComposer, scUserContext.user]);
// STATE
const [anchorNotification, setAnchorNotification] = React.useState(null);
// HANDLERS
const handleOpenNotificationMenu = (event) => {
setAnchorNotification(event.currentTarget);
onOpenNotificationMenu && onOpenNotificationMenu();
};
const handleCloseNotificationMenu = () => {
setAnchorNotification(null);
onCloseNotificationMenu && onCloseNotificationMenu();
};
// RENDER
if (scUserContext.loading) {
return _jsx(NavigationToolbarSkeleton, {});
}
const _children = children || (_jsxs(Box, Object.assign({ className: classes.navigation }, { children: [scUserContext.user && (_jsx(IconButton, Object.assign({ className: classNames(classes.home, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {})) }), "aria-label": "Home", to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "home" }) }))), preferences[SCPreferences.CONFIGURATIONS_EXPLORE_STREAM_ENABLED] &&
(preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && (_jsx(IconButton, Object.assign({ className: classNames(classes.explore, { [classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {})) }), "aria-label": "Explore", to: scRoutingContext.url(SCRoutes.EXPLORE_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "explore" }) }))), groupsEnabled && scUserContext.user && (_jsx(IconButton, Object.assign({ className: classNames(classes.groups, {
[classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {})) ||
value.startsWith(scRoutingContext.url(SCRoutes.GROUPS_ROUTE_NAME, {}))
}), "aria-label": "Groups", to: scRoutingContext.url(SCRoutes.GROUPS_SUBSCRIBED_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "groups" }) }))), eventsEnabled && (scUserContext.user || preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY]) && (_jsx(IconButton, Object.assign({ className: classNames(classes.events, {
[classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}))
}), "aria-label": "Events", to: scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}), component: Link }, { children: _jsx(Icon, { children: "CalendarIcon" }) })))] })));
return (_jsxs(Root, Object.assign({ className: classNames(className, classes.root) }, rest, { children: [_jsx(NavigationMenuIconButtonComponent, Object.assign({}, NavigationMenuIconButtonComponentProps)), _jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), !scUserContext.user && !preferences[SCPreferences.ADDONS_CLOSED_COMMUNITY] && (_jsx(Button, Object.assign({ color: "inherit", component: Link, to: scRoutingContext.url(SCRoutes.SIGNUP_ROUTE_NAME, {}), className: classes.register }, { children: _jsx(FormattedMessage, { id: "ui.appBar.navigation.register", defaultMessage: "ui.appBar.navigation.register" }) }))), preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_ENABLED] && (_jsx(_Fragment, { children: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT] ? (_jsx(Tooltip, Object.assign({ title: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_TEXT] }, { children: _jsx(Link, Object.assign({ target: "blank", to: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL], className: classes.customItem }, { children: _jsx("img", { src: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE], alt: "custom_item" }) })) }))) : (_jsx(Link, Object.assign({ target: "blank", to: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_URL], className: classes.customItem }, { children: _jsx("img", { src: preferences[SCPreferences.CONFIGURATIONS_CUSTOM_NAVBAR_ITEM_IMAGE], alt: "custom_item" }) }))) })), _children, (preferences[SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY] || scUserContext.user) && !disableSearch ? (_jsx(SearchAutocomplete, Object.assign({ className: classes.search, blurOnSelect: true }, SearchAutocompleteComponentProps))) : (_jsx(Box, { className: classes.search })), startActions, scUserContext.user ? (_jsxs(_Fragment, { children: [showComposer && _jsx(ComposerIconButton, Object.assign({ className: classes.composer }, ComposerIconButtonProps)), _jsx(Tooltip, Object.assign({ title: scUserContext.user.username }, { children: _jsx(IconButton, Object.assign({ component: Link, to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, scUserContext.user), "aria-label": "Profile", className: classes.profile }, { children: _jsx(Avatar, { alt: scUserContext.user.username, src: scUserContext.user.avatar }) })) })), _jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ className: classNames(classes.notification, {
[classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.USER_NOTIFICATIONS_ROUTE_NAME, {}))
}), "aria-label": "Notification", onClick: handleOpenNotificationMenu }, { children: _jsx(Badge, Object.assign({ badgeContent: scUserContext.user.unseen_notification_banners_counter + scUserContext.user.unseen_interactions_counter, color: "secondary" }, { children: _jsx(Icon, { children: "notifications_active" }) })) })), Boolean(anchorNotification) && (_jsx(NotificationMenu, Object.assign({ className: classes.notificationsMenu, id: "notification-menu", anchorEl: anchorNotification, open: true, onClose: handleCloseNotificationMenu, onClick: handleCloseNotificationMenu, transformOrigin: { horizontal: 'right', vertical: 'top' }, anchorOrigin: { horizontal: 'right', vertical: 'bottom' } }, NotificationMenuProps)))] }), privateMessagingEnabled && (_jsx(IconButton, Object.assign({ className: classNames(classes.messages, {
[classes.active]: value.startsWith(scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, {}))
}), "aria-label": "Messages", to: scRoutingContext.url(SCRoutes.USER_PRIVATE_MESSAGES_ROUTE_NAME, {}), component: Link }, { children: _jsx(Badge, Object.assign({ badgeContent: 0, color: "secondary" }, { children: _jsx(Icon, { children: "email" }) })) }))), endActions, _jsx(NavigationSettingsIconButtonComponent, { className: classes.settings })] })) : (_jsxs(_Fragment, { children: [endActions, _jsx(Button, Object.assign({ color: "inherit", component: Link, to: scRoutingContext.url(SCRoutes.SIGNIN_ROUTE_NAME, {}) }, { children: _jsx(FormattedMessage, { id: "ui.appBar.navigation.login", defaultMessage: "ui.appBar.navigation.login" }) }))] }))] })));
}