Skip to content

Commit

Permalink
Merge pull request #439 from AppQuality/UN-350-banner
Browse files Browse the repository at this point in the history
feat: global alert
  • Loading branch information
iacopolea authored Nov 13, 2024
2 parents be480dd + a6732a4 commit 42390b0
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export * from "./stories/navigation/nav/nav-item";

// --- Notifications ---
export * from "./stories/notifications";
export * from "./stories/notifications/global-alert";

// --- Pagination ---
export * from "./stories/pagination";
Expand Down
35 changes: 35 additions & 0 deletions src/stories/notifications/global-alert/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Meta as ComponentMeta, StoryFn as Story } from "@storybook/react";
import {
GlobalAlert as UgGlobalAlert,
GlobalAlertProps
} from ".";
import { Anchor } from "../../buttons/anchor";

const GlobalAlertTemplate: Story<GlobalAlertProps> = ({ ...props }) => (
<UgGlobalAlert {...props}>
</UgGlobalAlert>
);

export const GlobalAlert = GlobalAlertTemplate.bind({});
GlobalAlert.args = {
type: "info",
title: "Account update",
dismissable: true,
onClose: () => {alert('dismissed')},
cta: "Find out more",
message: <>
Your account will automatically update in 5 days.{' '}
<Anchor href="#" isExternal>
Find out more
</Anchor>
</>
};

export default {
title: "Molecules/Notification",
component: UgGlobalAlert,
parameters: {
// Sets a delay for the component's stories
chromatic: { delay: 300 },
},
} as ComponentMeta<typeof UgGlobalAlert>;
145 changes: 145 additions & 0 deletions src/stories/notifications/global-alert/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import {
GlobalAlert as ZendeskGlobalAlert,
IGlobalAlertProps
} from "@zendeskgarden/react-notifications";
import { forwardRef, ReactNode } from "react";
import styled from "styled-components";
import { getColor } from "../../theme/utils";
import { ButtonArgs } from "../../buttons/button/_types";
import { Button } from "../../buttons/button";
import { ReactComponent as AccentIcon } from "@zendeskgarden/svg-icons/src/16/lightbulb-stroke.svg";
import { ReactComponent as PrimaryIcon } from "@zendeskgarden/svg-icons/src/16/gear-stroke.svg";

export interface GlobalAlertProps extends Omit<IGlobalAlertProps, 'type'> {
type: IGlobalAlertProps['type'] | "accent" | "primary";
message?: ReactNode;
dismissable?: boolean;
onClose?: () => void;
cta?: string;
}

const StyledGlobalAlert = styled(ZendeskGlobalAlert) <GlobalAlertProps>`
// general
align-items: center;
[data-garden-id="notifications.global-alert.icon"] {
margin-top: -2px;
}
.global-alert-icon {
flex-shrink: 0;
margin-top: -2px;
margin-right: 8px;
width: 16px;
height: 16px;
}
.global-alert-cta {
flex-shrink: 0;
}
// looks like the following rules get overwritten by garden if we use props.type directly instead of alerttype
// or even in file component.ts of the theme
// Primary
&[alerttype="primary"] {
background-color: ${({ theme }) => getColor(theme.colors.primaryHue, 100)};
color: ${({ theme }) => getColor(theme.colors.primaryHue, 700)};
box-shadow: 0 1px 1px ${({ theme }) => getColor(theme.colors.primaryHue, 300)};
[data-garden-id="notifications.global-alert.content"] {
color: ${({ theme }) => getColor(theme.colors.primaryHue, 700)};
}
[data-garden-id="notifications.global-alert.title"] {
color: ${({ theme }) => getColor(theme.colors.primaryHue, 800)};
}
[data-garden-id="buttons.anchor"] {
color: ${({ theme }) => getColor(theme.colors.primaryHue, 600)};
}
.global-alert-icon {
color: ${({ theme }) => getColor(theme.colors.primaryHue, 700)};
}
}
// Accent
&[alerttype="accent"] {
background-color: ${({ theme }) => theme.palette.blue[100]};
color: ${({ theme }) => getColor(theme.colors.primaryHue, 700)};
box-shadow: 0 1px 1px ${({ theme }) => getColor(theme.colors.accentHue, 600)};
[data-garden-id="notifications.global-alert.content"] {
color: ${({ theme }) => getColor(theme.colors.accentHue, 700)};
}
[data-garden-id="notifications.global-alert.title"] {
color: ${({ theme }) => getColor(theme.colors.accentHue, 800)};
}
[data-garden-id="buttons.anchor"] {
color: ${({ theme }) => getColor(theme.colors.accentHue, 700)};
}
.global-alert-icon {
color: ${({ theme }) => getColor(theme.colors.accentHue, 700)};
}
}
// Info
&[alerttype="info"] {
background-color: ${({ theme }) => getColor(theme.colors.infoHue, 100)};
color: ${({ theme }) => getColor(theme.colors.primaryHue, 700)};
[data-garden-id="notifications.global-alert.content"] {
color: ${({ theme }) => getColor(theme.colors.infoHue, 700)};
}
[data-garden-id="notifications.global-alert.title"] {
color: ${({ theme }) => getColor(theme.colors.infoHue, 800)};
}
[data-garden-id="buttons.anchor"] {
color: ${({ theme }) => getColor(theme.colors.infoHue, 700)};
}
[data-garden-id="notifications.global-alert.icon"] {
color: ${({ theme }) => getColor(theme.colors.infoHue, 700)};
}
}
// Error
&[alerttype="error"] {
.global-alert-cta {
background-color: ${({ theme }) => getColor(theme.colors.dangerHue, 800)};
}
}
// Warning
&[alerttype="warning"] {
background-color: ${({ theme }) => getColor(theme.colors.warningHue, 300)};
box-shadow: 0 1px 1px ${({ theme }) => getColor(theme.colors.warningHue, 600)};
.global-alert-cta {
background-color: ${({ theme }) => getColor(theme.colors.warningHue, 800)};
}
}
// Success
&[alerttype="success"] {
background-color: ${({ theme }) => getColor(theme.colors.successHue, 700)};
box-shadow: 0 1px 1px ${({ theme }) => getColor(theme.colors.successHue, 700)};
color: ${({ theme }) => getColor(theme.colors.successHue, 50)};
.global-alert-cta {
background-color: ${({ theme }) => getColor(theme.colors.successHue, 800)};
}
}
`;

const CustomButton = ({ isPill = true, isPrimary = true, ...props }: ButtonArgs) => (
<Button isPill={isPill} isPrimary={isPrimary} size="small" {...props} />
);

export const GlobalAlert = forwardRef<HTMLDivElement, GlobalAlertProps>(({ type, onClose, dismissable, cta, title, message, ...props }, ref) => (
<StyledGlobalAlert ref={ref} type={type} {...props}>
{type === "accent" && <AccentIcon className="global-alert-icon"/>}
{type === "primary" && <PrimaryIcon className="global-alert-icon" />}
<StyledGlobalAlert.Content>
{title && <StyledGlobalAlert.Title>{title}</StyledGlobalAlert.Title>}
{message}
</StyledGlobalAlert.Content>
{cta && <CustomButton className="global-alert-cta" isAccent={type==='accent'}>{cta}</CustomButton>}
{dismissable && <StyledGlobalAlert.Close aria-label="Close Global Alert" onClick={onClose} />}
</StyledGlobalAlert>
));

0 comments on commit 42390b0

Please sign in to comment.