-
Notifications
You must be signed in to change notification settings - Fork 34
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
Changes from 6 commits
1789a55
09e08e0
2d81ef2
03e8d43
4437959
d6f3c07
b8ef316
6ccd3f9
309e6c9
0caf237
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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<{ | ||
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; |
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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just use There was a problem hiding this comment. Choose a reason for hiding this commentThe 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! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch!! I moved this into the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 ifcollapsible
is trueThere was a problem hiding this comment.
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?