@spaced-out/ui-design-system
Version:
Sense UI components library
268 lines (249 loc) • 6.11 kB
Flow
// @flow strict
import * as React from 'react';
import {
colorIconPrimary,
colorIconSecondary,
} from '../../styles/variables/_color';
import classify from '../../utils/classify';
import {Button} from '../Button';
import {Icon} from '../Icon';
import {TEXT_COLORS, TitleMedium} from '../Text';
import {Tooltip} from '../Tooltip';
import css from './PageTitle.module.css';
type ClassNames = $ReadOnly<{
wrapper?: string,
leftSlot?: string,
rightSlot?: string,
}>;
export type PageTitleProps = {
classNames?: ClassNames,
children?: React.Node,
pageNameKey?: string,
showBackButton?: boolean,
onBack?: () => void,
};
export const PAGE_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',
},
workflows: {
title: 'Workflows',
iconName: 'bullseye-pointer',
iconType: 'duotone',
},
trm: {
title: 'TRM',
iconName: 'screen-users',
iconType: 'duotone',
},
analytics: {
title: 'Analytics',
iconName: 'chart-column',
iconType: 'duotone',
},
messaging: {
title: 'Messaging',
iconName: 'messages',
iconType: 'duotone',
},
chatbot: {
title: 'Chatbot',
iconName: 'message-bot',
iconType: 'duotone',
},
referrals: {
title: 'Referrals',
iconName: 'user-check',
iconType: 'duotone',
},
records: {
title: 'Records',
iconName: 'folder-open',
iconType: 'duotone',
},
bulkCleanup: {
title: 'Bulk Cleanup',
iconName: 'retweet',
iconType: 'duotone',
},
support: {
title: 'Support',
iconName: 'headset',
iconType: 'duotone',
},
audit: {
title: 'Audit',
iconName: 'print-magnifying-glass',
iconType: 'duotone',
},
timeline: {
title: 'Timeline',
iconName: 'timeline',
iconType: 'duotone',
},
people: {
title: 'People',
iconName: 'people-group',
iconType: 'duotone',
},
jobs: {
title: 'Jobs',
iconName: 'briefcase',
iconType: 'duotone',
},
contacts: {
title: 'Contacts',
iconName: 'address-card',
iconType: 'duotone',
},
meetings: {
title: 'Meetings',
iconName: 'calendars',
iconType: 'duotone',
},
contacts3: {
title: 'Contacts',
iconName: 'browser',
iconType: 'duotone',
},
tracking: {
title: 'Tracking',
iconName: 'user-check',
iconType: 'duotone',
},
earnings: {
title: 'Earnings',
iconName: 'wallet',
iconType: 'duotone',
},
settings: {
title: 'Settings',
iconName: 'gear',
iconType: 'duotone',
},
broadcast: {
title: 'Broadcast',
iconName: 'bullhorn',
iconType: 'duotone',
},
});
export type TabSlotProps = {
children?: React.Node,
className: string,
...
};
export const TabSlot = ({
children,
className,
...props
}: TabSlotProps): React.Node => (
<div {...props} className={classify(css.tabSlot, className)}>
{children}
</div>
);
TabSlot.displayName = 'TabSlot';
export type RightSlotProps = {
children?: React.Node,
...
};
export const RightSlot = ({children, ...props}: RightSlotProps): React.Node => (
<div {...props}>{children}</div>
);
RightSlot.displayName = 'RightSlot';
export type PageNameProps = {
children?: React.Node,
...
};
export const PageName = ({children, ...props}: PageNameProps): React.Node => (
<div {...props} className={css.pageTitle}>
{children}
</div>
);
PageName.displayName = 'PageName';
export const PageTitle: React$AbstractComponent<
PageTitleProps,
HTMLDivElement,
> = React.forwardRef<PageTitleProps, HTMLDivElement>(
(
{classNames, children, pageNameKey, showBackButton, onBack}: PageTitleProps,
ref,
): React.Node => {
const getNamedComp = (comp: string) => {
const childrenArray = React.Children.toArray(children);
if (childrenArray.length) {
const nodes: React.Node[] = [];
for (const child of childrenArray) {
if (child?.type?.displayName === comp) {
nodes.push(child);
}
}
return nodes.length > 1 ? nodes : nodes[0];
}
return null;
};
const handleBack = () => {
onBack && onBack();
};
return (
<div
data-testid="PageTitle"
className={classify(css.pageTitleWrapper, classNames?.wrapper)}
ref={ref}
>
<div className={classify(css.leftSlot, classNames?.leftSlot)}>
<div className={css.headerWithBackBtn}>
{showBackButton && (
<Tooltip
title="Navigate Back"
delayMotionDuration="slow"
placement="top-start"
>
<Button
onClick={handleBack}
type="tertiary"
iconLeftName="chevron-left"
ariaLabel="Navigate Back Button"
/>
</Tooltip>
)}
{pageNameKey && PAGE_NAME_LIST[pageNameKey] ? (
<PageName>
<TitleMedium>{PAGE_NAME_LIST[pageNameKey].title} </TitleMedium>
<Icon
type={PAGE_NAME_LIST[pageNameKey].iconType}
name={PAGE_NAME_LIST[pageNameKey].iconName}
size="medium"
color={TEXT_COLORS.primary}
style={{
'--fa-primary-color': colorIconPrimary,
'--fa-secondary-color': colorIconSecondary,
'--fa-primary-opacity': '1.0',
'--fa-secondary-opacity': '1.0',
}}
/>
</PageName>
) : (
getNamedComp('PageName')
)}
</div>
{getNamedComp('TabSlot')}
</div>
<div className={classify(css.rightSlot, classNames?.rightSlot)}>
{getNamedComp('RightSlot')}
</div>
</div>
);
},
);