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

Create Alert Component #744

Merged
merged 10 commits into from
Nov 5, 2024
6 changes: 5 additions & 1 deletion packages/building-blocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"peerDependencies": {
"react": "^18.2.0",
"react-animate-height": "^3.0.4",
"styled-components": "^5.3.0"
},
"repository": {
Expand All @@ -27,5 +28,8 @@
"bugs": {
"url": "https://github.com/opentripplanner/otp-ui/issues"
},
"gitHead": "0af1b7cda60bd4252b219dcf893e01c2acb2ed5d"
"gitHead": "0af1b7cda60bd4252b219dcf893e01c2acb2ed5d",
"dependencies": {
"@styled-icons/bootstrap": "^10.47.0"
}
}
125 changes: 125 additions & 0 deletions packages/building-blocks/src/Alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import React, { ReactChild, useState } from "react";
import styled from "styled-components";
import AnimateHeight from "react-animate-height";
import { ChevronUp } from "@styled-icons/bootstrap/ChevronUp";
import { Bell } from "@styled-icons/bootstrap/Bell";
import { StyledIcon } from "@styled-icons/styled-icon";
import blue from "./colors/blue";

interface Props {
alertHeader: string;
alertSubheader?: string;
backgroundColor?: string;
collapsible?: boolean;
children?: ReactChild;
Icon?: StyledIcon;
}

const AlertContainer = styled.div<{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider going more semantic and using a details tag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think this would actually make the component less customizable, since details always has a toggle, and this alert currently only has a toggle if collapsible is true

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to hide the toggle with CSS?

backgroundColor: string;
collapsible: boolean;
expandAlert: boolean;
}>`
background-color: ${props =>
props.backgroundColor ? props.backgroundColor : blue[50]};
display: grid;
grid-template-columns: 50px auto auto;
grid-template-rows: minmax(25px, auto) auto;
max-width: 715px;
padding: 1.5em 2em;

svg {
align-self: center;
grid-column: 1;
grid-row: 1 / span 2;
justify-self: start;
}

button {
background: transparent;
border: none;
width: 40px;

svg {
transform: ${props => !props.expandAlert && "rotate(180deg)"};
transition: all 0.2s ease-in;
}
}

@media (max-width: 550px) {
grid-template-columns: 40px auto auto;
padding: 1.25em 1.25em;
}
`;

const ButtonContainer = styled.span`
align-items: center;
display: flex;
justify-content: center;
justify-self: right;
`;

const AlertHeader = styled.span`
align-self: center;
font-weight: 700;
grid-column: 2;
`;

const AlertSubheader = styled(AlertHeader)`
font-weight: 400;
margin-top: 0.3em;
`;

const AlertContent = styled.div`
grid-column: 2;
grid-row: 3;
`;

const ContentPadding = styled.div<{
collapsible: boolean;
}>`
margin-top: ${props => (props.collapsible ? "1em" : ".5em")};
`;

const Alert = ({
alertHeader,
alertSubheader,
backgroundColor,
children,
collapsible,
Icon = Bell
}: Props): JSX.Element => {
const [expandAlert, setExpandAlert] = useState(false);
return (
<AlertContainer
backgroundColor={backgroundColor}
expandAlert={expandAlert}
collapsible={collapsible}
>
<Icon size={24} />
<AlertHeader>{alertHeader}</AlertHeader>
<ButtonContainer>
{collapsible && (
<button type="button" onClick={() => setExpandAlert(!expandAlert)}>
<ChevronUp size={16} />
</button>
)}
</ButtonContainer>
{alertSubheader && <AlertSubheader>{alertSubheader}</AlertSubheader>}
{children && (
<AlertContent>
<AnimateHeight
duration={500}
height={collapsible ? (expandAlert ? "auto" : 0) : "auto"}
>
<ContentPadding collapsible={collapsible}>
{children}
</ContentPadding>
</AnimateHeight>
</AlertContent>
)}
</AlertContainer>
);
};

export default Alert;
78 changes: 78 additions & 0 deletions packages/building-blocks/src/stories/alerts.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, { ReactElement } from "react";
import { Meta } from "@storybook/react";
import { ExclamationTriangle } from "@styled-icons/bootstrap/ExclamationTriangle";
import Alert from "../Alert";
import red from "../colors/red";

const meta: Meta<typeof Alert> = {
title: "Building-Blocks/Alert",
component: Alert
};

export default meta;

const alerts = [
{
alertUrl: "http://trimet.org/alerts/",
effectiveStartDate: 1576471800,
alertDescriptionText:
"TriMet Customer Service will be unavailable to serve text messages or Twitter responses from 9:00 p.m.- 11:30 p.m. For immediate assistance regarding safety or security concerns, please contact the police via 911."
},
{
alertUrl:
"https://news.trimet.org/2019/11/next-up-for-elevator-improvements-sunset-transit-center-park-ride/",
effectiveStartDate: 1573083439,
alertDescriptionText:
"The Park and Ride garage elevator at Sunset Transit Center is closed for approximately 3 months for improvements. During this time garage users must use the stairs or find alternate parking. Visit trimet.org/parkandride for a complete list of Park and Ride garages."
},
{
alertUrl: "http://trimet.org/alerts/",
effectiveStartDate: 1572827580,
alertDescriptionText:
"The west elevators at the Washington Park MAX Station are out of service. Please use east elevators to access street level and platforms. "
}
];

const alertKey = crypto.randomUUID();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use i for the key? Does that break something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually yeah this is bad because all the keys will all be the same!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!! I moved this into the map so it actually does what it's supposed to do, although I guess i would work in this case because the order of the mock alerts in this story isn't going to change? Happy to change it if someone feels strongly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I didn't realize this is just the story. It's fine, stories don't have to be perfect!


const AlertContent = () => {
return (
<>
{alerts.map((alert, i) => {
return (
<>
<div key={alertKey}>
{`${i + 1}) `}
{alert.alertDescriptionText}
</div>
<br />
</>
);
})}
</>
);
};

export const BasicAlert = (): ReactElement => {
return (
<Alert
alertHeader="Next trip starts on Wednesday April 17th"
alertSubheader="Trip is due to begin at 7:43 AM (Realtime monitoring will being at 7:13 AM)"
>
Here is more content
</Alert>
);
};

export const CollapsibleAlertWithTransitAlerts = (): ReactElement => {
return (
<Alert
backgroundColor={red[50]}
collapsible
Icon={ExclamationTriangle}
alertHeader="Your trip has alerts"
>
<AlertContent />
</Alert>
);
};
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6168,6 +6168,14 @@
"@babel/runtime" "^7.14.0"
"@styled-icons/styled-icon" "^10.6.3"

"@styled-icons/bootstrap@^10.47.0":
version "10.47.0"
resolved "https://registry.yarnpkg.com/@styled-icons/bootstrap/-/bootstrap-10.47.0.tgz#c3e363dfe87b732a5da818f320f90f5ab4961b84"
integrity sha512-xpnPdrLhAhpTRE4iljQIEK73twVj7VPglwHSL+8nQdH7EsW5RJIOWsmlkZMyqhQHN0H7fGmT10F3/6OQhSpfGg==
dependencies:
"@babel/runtime" "^7.20.7"
"@styled-icons/styled-icon" "^10.7.0"

"@styled-icons/[email protected]":
version "10.38.0"
resolved "https://registry.yarnpkg.com/@styled-icons/boxicons-logos/-/boxicons-logos-10.38.0.tgz#f51442c49f1a28c61927d6d2f8c1e2d7946faf46"
Expand Down
Loading