UNPKG

@spaced-out/ui-design-system

Version:
345 lines (331 loc) 8.19 kB
// @flow strict import * as React from 'react'; import classify from '../../utils/classify'; import {UnstyledButton} from '../Button'; import {ConditionalWrapper} from '../ConditionalWrapper'; import {Icon} from '../Icon'; import type {BaseLinkProps} from '../Link'; import {Link} from '../Link'; import type {StatusSemanticType} from '../StatusIndicator'; import {StatusIndicator} from '../StatusIndicator'; import {BodyMedium, SubTitleSmall, TEXT_COLORS} from '../Text'; import type {BaseTooltipProps} from '../Tooltip'; import {Tooltip} from '../Tooltip'; import css from './SideMenuLink.module.css'; export const MENU_NAME_LIST = Object.freeze({ dashboard: { title: 'Dashboard', iconName: 'house', iconType: 'duotone', }, engage: { title: 'Engage', iconName: 'bullseye-pointer', iconType: 'duotone', }, journeys: { title: 'Journeys', iconName: 'bullseye-pointer', iconType: 'duotone', }, automation: { title: 'Automation', iconName: 'bullseye-pointer', iconType: 'duotone', }, trm: { title: 'TRM', iconName: 'screen-users', iconType: 'duotone', }, analytics: { title: 'Analytics & Data', iconName: 'chart-column', iconType: 'duotone', }, messaging: { title: 'Messaging', iconName: 'messages', iconType: 'duotone', }, messages: { title: 'Messaging', iconName: 'messages', iconType: 'duotone', }, chatbot: { title: 'Chatbot', iconName: 'message-bot', iconType: 'duotone', }, referral: { title: 'Referrals', iconName: 'user-check', iconType: 'duotone', }, referrals: { title: 'Referrals', iconName: 'user-check', iconType: 'duotone', }, records: { title: 'Records', iconName: 'folder-open', iconType: 'duotone', }, 'database-cleanup': { title: 'Bulk Cleanup', iconName: 'retweet', iconType: 'duotone', }, support: { title: 'Support', iconName: 'headset', iconType: 'duotone', }, audit: { title: 'Audit', iconName: 'print-magnifying-glass', iconType: 'duotone', }, schedule: { title: 'Timeline', iconName: 'timeline', iconType: 'duotone', }, people: { title: 'People', iconName: 'people-group', iconType: 'duotone', }, contacts: { title: 'Contacts', iconName: 'address-card', iconType: 'duotone', }, meetings: { title: 'Meetings', iconName: 'calendars', iconType: 'duotone', }, contacts3: { title: 'Contacts', iconName: 'browser', iconType: 'duotone', }, senseai: { title: 'AI Copilot', iconName: 'sparkles', iconType: 'duotone', }, 'sense-jd-ai': { title: 'Jd generator', iconName: 'sparkles', iconType: 'duotone', }, tracking: { title: 'Tracking', iconName: 'user-check', iconType: 'duotone', }, jobs: { title: 'Jobs', iconName: 'briefcase', iconType: 'duotone', }, drive: { title: 'Events', iconName: 'briefcase', iconType: 'duotone', }, conversations: { title: 'Conversations', iconName: 'message-smile', iconType: 'duotone', }, pages: { title: 'Pages', iconName: 'pager', iconType: 'duotone', }, sourcing: { title: 'Sourcing', iconName: 'browser', iconType: 'duotone', }, earnings: { title: 'Earnings', iconName: 'wallet', iconType: 'duotone', }, settings: { title: 'Settings', iconName: 'gear', iconType: 'duotone', }, configuration: { title: 'Configuration', iconName: 'gear', iconType: 'duotone', }, supportLinks: { title: 'Support Links', iconName: 'circle-question', iconType: 'duotone', }, voiceflow: { title: 'Voiceflow', iconName: 'phone-volume', iconType: 'duotone', }, broadcast: { title: 'Broadcast', iconName: 'bullhorn', iconType: 'duotone', }, liveAgentTransfer: { title: 'Live Agent Transfer', iconName: 'user-headset', iconType: 'duotone', }, dataManagement: { title: 'Data Management', iconName: 'database', iconType: 'duotone', }, }); type ClassNames = $ReadOnly<{wrapper?: string}>; export type SideMenuLinkProps = { classNames?: ClassNames, children?: React.Node, customTitle?: string, pageNameKey: string, disabled?: boolean, hovered?: boolean, selectedValue?: string, opened?: boolean, onChange?: (e: SyntheticEvent<HTMLElement>, newValue: string) => mixed, tabIndex?: number, tooltip?: BaseTooltipProps, isGroupMenuLink?: boolean, to?: string, rightSlot?: React.Node, linkComponent?: React.AbstractComponent<BaseLinkProps, ?HTMLAnchorElement>, status?: StatusSemanticType, ... }; export const SideMenuLink: React$AbstractComponent< SideMenuLinkProps, HTMLButtonElement, > = React.forwardRef<SideMenuLinkProps, HTMLButtonElement>( ( { classNames, pageNameKey, disabled, opened, selectedValue, onChange, tabIndex = 0, tooltip, isGroupMenuLink = false, linkComponent: LinkComponent, rightSlot, to, customTitle, status, ...restButtonProps }: SideMenuLinkProps, ref, ): React.Node => { const selected = selectedValue === pageNameKey; const inActive = !onChange; const onChangeHandler = (e: SyntheticEvent<HTMLElement>) => { onChange && onChange(e, pageNameKey); }; const linkTitle = customTitle || MENU_NAME_LIST[pageNameKey].title; return ( <ConditionalWrapper condition={to !== undefined} wrapper={(children) => ( <Link to={to} tabIndex={-1} linkComponent={LinkComponent} className={classify(css.linkComponent, { [css.closed]: !opened, })} onClick={onChangeHandler} > {children} </Link> )} > <ConditionalWrapper condition={Boolean(!opened && !inActive)} wrapper={(children) => ( <Tooltip body={linkTitle} {...tooltip}> {children} </Tooltip> )} > <UnstyledButton {...restButtonProps} className={classify( css.linkWrapper, { [css.selected]: selected, [css.disabled]: disabled, [css.inActive]: inActive, [css.closed]: !opened, }, classNames?.wrapper, )} onClick={onChangeHandler} ref={ref} tabIndex={disabled ? -1 : tabIndex} disabled={disabled} key={pageNameKey} > {pageNameKey && MENU_NAME_LIST[pageNameKey] ? ( <div className={css.iconContainer}> {status && ( <StatusIndicator status={status} classNames={{ wrapper: css.statusIndicatorBlock, }} /> )} <Icon type={MENU_NAME_LIST[pageNameKey].iconType} name={MENU_NAME_LIST[pageNameKey].iconName} size="medium" color={TEXT_COLORS.inverseSecondary} className={css.menuIcon} /> </div> ) : null} {opened ? ( <div className={css.menuLabelContainer}> {pageNameKey && MENU_NAME_LIST[pageNameKey] ? ( isGroupMenuLink ? ( <SubTitleSmall className={css.groupMenuLinkText}> {linkTitle} </SubTitleSmall> ) : ( <BodyMedium className={css.menuLinkText}> {linkTitle} </BodyMedium> ) ) : null} {rightSlot ? rightSlot : null} </div> ) : null} </UnstyledButton> </ConditionalWrapper> </ConditionalWrapper> ); }, ); SideMenuLink.displayName = 'SideMenuLink';