Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added user type badge to top bar and tweaked buttons states #509

Merged
merged 17 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/example/src/pages/Layouts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ const Layouts: FC = () => {
switchThemeText='SWITCH THEME'
selectedThemeText={isLightMode ? 'LIGHT MODE' : 'DARK MODE' }
onThemeToggle={onThemeToggle}
badge={{
text: 'Guest',
color: 'primary',
linkTo: '#',
linkText: 'Login'
}}
hasSwitchTheme
content={{
items: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@ export const _DatePicker = () => {
/>
</FilterDropdownContainer>
</Container>);
};
};
12 changes: 11 additions & 1 deletion packages/storybook/src/stories/Global/GlobalUI.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { Route, Switch, RouteComponentProps } from 'react-router-dom';
import logoMarkSvg from '../assets/logo-mark.svg';
import logoTextSvg from '../assets/logo-text.svg';

import { text, object, boolean } from '@storybook/addon-knobs';
import { text, object, boolean, select } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

export default {
Expand Down Expand Up @@ -419,6 +419,10 @@ export const _GlobalUI = () => {
icon: 'Information',
title: 'V12.3.4',
});
const badgeText = text("Badge Text", "Guest");
const badgeColor = select("Badge Color", ['primary', 'grey', 'info', 'success', 'caution', 'warning'], 'info');
const badgeLinkTo = text("Badge To", "/login");
const badgeLinkText = text("Badge Link Text", "Login");

const menuConfig = object("Menu Config", {
items: [
Expand Down Expand Up @@ -557,6 +561,12 @@ export const _GlobalUI = () => {
canAlwaysPin={canAlwaysPin}
userDrawerMeta={userDrawerMetaConfig}
legacyLayout={false}
badge={{
text: badgeText,
color: badgeColor,
linkTo: badgeLinkTo,
linkText: badgeLinkText
}}
{...{ logoMark, logoText, supportUrl, maxWidth, paddingOverride, notificationsHistory, customDrawer}}
{...{ loggedInUser, userSubmenu, hasSearch, hasLogout, hasNotifications, logoutLink, logoutText, searchPlaceholder, hasLanguage,
hasCurrentUser, currentUserText, accountOptionText, userDrawerFooter, hasUserDrawerMeta, copySuccessMessage, includeCopyTitle, hasUserDrawerFooter,
Expand Down
18 changes: 15 additions & 3 deletions packages/storybook/src/stories/Global/TopBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ReactElement } from 'react';
import styled from 'styled-components';
import { object, text, boolean } from "@storybook/addon-knobs";
import { object, text, boolean, select } from "@storybook/addon-knobs";
import { TopBar, ICustomDrawer, INotificationItem, INotificationsHistory, useThemeToggle } from 'scorer-ui-kit';
import { action } from '@storybook/addon-actions';

Expand Down Expand Up @@ -159,6 +159,11 @@ export const _TopBar = () => {
]
);

const badgeText = text("Badge Text", "Guest");
const badgeColor = select("Badge Color", ['primary', 'grey', 'info', 'success', 'caution', 'warning'], 'info');
const badgeLinkTo = text("Badge To", "/login");
const badgeLinkText = text("Badge Link Text", "Login");

// userDrawerBespoke: See examples for implementation of this prop.

const onLanguageToggle = () => {
Expand All @@ -167,7 +172,14 @@ export const _TopBar = () => {

return (
<Container>
<TopBar {...{
<TopBar
badge={{
text: badgeText,
color: badgeColor,
linkTo: badgeLinkTo,
linkText: badgeLinkText
}}
{...{
loggedInUser,
userSubmenu,
hasSearch,
Expand All @@ -191,7 +203,7 @@ export const _TopBar = () => {
logoutText,
userDrawerFooter,
copySuccessMessage,
includeCopyTitle
includeCopyTitle,
}}
userDrawerMeta={userDrawerMetaConfig}
customDrawer={drawerProps}
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-lib/src/Filters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ export type {
IFilterDatePicker,
FilterButtonDesign,
DateRange
};
};
149 changes: 149 additions & 0 deletions packages/ui-lib/src/Global/atoms/TopBarBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React, { useEffect, useState, useRef, Fragment } from 'react';
import styled, { css } from 'styled-components';
import { Link } from 'react-router-dom';
import { ITopBarBadge } from '..';

const CoreStyle = css`
display: flex;
height: 32px;
padding: 8px;
align-items: center;
justify-content: center;
text-align: center;
gap: 8px;
border-radius: 3px;

font-family: Lato;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 12px; /* 85.714% */
white-space: nowrap;

transition: opacity var(--speed-fast) var(--easing-primary-out);

`;

const ContainerStatic = styled.div<{themeColor?: string}>`
${CoreStyle};

${({themeColor}) => themeColor ? css`
border: 2px solid var(--${themeColor}-9);
color: var(--${themeColor}-11);
` : css`
border: 2px solid var(--info-9);
color: var(--info-11);
`};
`;

const DefaultText = styled.span`
display: inline-block;
`;
const LinkText = styled.span``;

const ContainerLinked = styled.div<{themeColor?: string}>`
a {
${CoreStyle};

text-decoration: none;

${({themeColor}) => themeColor ? css`
background-color: transparent;
border: 2px solid var(--${themeColor}-9);
color: var(--${themeColor}-11);
` : css`
background-color: transparent;
border: 2px solid var(--info-9);
color: var(--info-11);
`};

&:hover {
${({themeColor}) => themeColor ? css`
background-color: var(--${themeColor}-9);
border: 2px solid var(--${themeColor}-9);
color: var(--white-12);
` : css`
background-color: var(--info-9);
border: 2px solid var(--info-9);
color: var(--white-12);
`};
}
}
`;

const Container = styled.div<{ready: boolean, minWidth: number}>`
${({ready, minWidth}) => css`

visibility: ${ready ? 'visible' : 'hidden'};
opacity: ${ready ? '1' : '0'};

transition: opacity var(--speed-fast) var(--easing-primary-in-out);

${DefaultText}, ${LinkText}{
/* Required to accurately measure container sizes and ensure hover doesn't resize. */
${ready && `min-width: ${minWidth}px;`};
}
`};
`;

const TopBarBadge: React.FC<ITopBarBadge> = ({text, color, linkHref, linkTo, linkText}) => {

const defaultTextRef = useRef() as React.MutableRefObject<HTMLSpanElement>;
const linkTextRef = useRef() as React.MutableRefObject<HTMLSpanElement>;

const [ready, setReady] = useState<boolean>(false);
const [hover, setHover] = useState<boolean>(false);
const [minWidth, setMinWidth] = useState<number>(0);

useEffect(() => {
setReady(false);
setTimeout(() => {
const defaultWidth = defaultTextRef.current.getBoundingClientRect().width;
const linkWidth = linkTextRef.current?.getBoundingClientRect().width || 0;
const largestWidth = defaultWidth >= linkWidth ? defaultWidth : linkWidth;
setMinWidth(Math.ceil(largestWidth));
setReady(true);
}, 100);
}, [defaultTextRef, linkTextRef, text, linkText, setMinWidth, setReady]);

const defaultTextElement = <DefaultText ref={defaultTextRef}>{text}</DefaultText>;
const linkTextElement = linkTo || linkHref ? <LinkText ref={linkTextRef}>{linkText || text}</LinkText> : null;

let badgeComponent;

if(linkTo){
badgeComponent = <ContainerLinked themeColor={color}>
<Link to={linkTo}>
{ !ready ? <Fragment>
{defaultTextElement}
{linkTextElement}
</Fragment>
: <Fragment>
{!hover ? defaultTextElement : linkTextElement }
</Fragment>}
</Link>
</ContainerLinked>;
} else if(linkHref){
badgeComponent = <ContainerLinked themeColor={color}>
<a href={linkHref}>
{ !ready ? <Fragment>
{defaultTextElement}
{linkTextElement}
</Fragment>
: <Fragment>
{!hover ? defaultTextElement : linkTextElement }
</Fragment>}
</a>
</ContainerLinked>;
} else {
badgeComponent = <ContainerStatic themeColor={color}>{defaultTextElement}</ContainerStatic>;
}

return (
<Container {...{ready, minWidth}} onPointerEnter={ () => ready && setHover(true) } onPointerLeave={ () => ready && setHover(false) }>
{ badgeComponent }
</Container>
);
};

export default TopBarBadge;
9 changes: 9 additions & 0 deletions packages/ui-lib/src/Global/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export interface IMenuTop {
copySuccessMessage?: string,
includeCopyTitle?: boolean
hasUserDrawerFooter?: boolean
badge?: ITopBarBadge;
}

export interface INotificationItem {
Expand All @@ -132,4 +133,12 @@ export interface IMenuTop {
noNotificationsText?: string
readNotificationsText?: string
unreadNotificationsText?: string
}

export interface ITopBarBadge {
text: string;
color?: string;
linkHref?: string;
linkTo?: string;
linkText?: string;
}
Loading
Loading