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

Earth dot gov carousel #149

Merged
merged 36 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9d84bce
Add content for earth.gov carousel
freitagb Nov 12, 2024
3eca722
add carousel to homepage
freitagb Nov 12, 2024
9de8e11
adding banner image for global sea level rise portal
freitagb Nov 12, 2024
359d6d4
dropped comma in items.js
freitagb Nov 12, 2024
145df07
fix path to images
freitagb Nov 12, 2024
e338d47
fixed configuration
Nov 12, 2024
a31b53b
updated text in carousel
Nov 12, 2024
794e410
update titles and images
Nov 12, 2024
1e22710
added carousel on SLR themes page
Nov 12, 2024
76e9c0c
fixed function call
Nov 12, 2024
ad031e2
updated theme carousel for SLR
Nov 12, 2024
94ce926
updated theme carousel for SLR
Nov 12, 2024
8ccc421
dropped semi-colon
Nov 12, 2024
bcadc86
formatting?
Nov 12, 2024
8a2ac3f
update import
Nov 12, 2024
7a32885
Fix the import in mdx
amarouane-ABDELHAK Nov 12, 2024
f0ae9d1
Rename the carousel folder to prevent the naming collision
amarouane-ABDELHAK Nov 12, 2024
a7bb5cb
add text
Nov 13, 2024
eed5b07
updated portal description text
Nov 13, 2024
740171d
testing layout of carousel on slr theme page
freitagb Nov 13, 2024
2f25714
Update overrides/home/carousel/items.js
freitagb Nov 14, 2024
ac91555
Delete overrides/home/media/global-slr.jpg
freitagb Nov 14, 2024
d6c3093
Update items.js
freitagb Nov 14, 2024
fc9d373
Update alt text for global site
freitagb Nov 14, 2024
6921bd2
fix alignment on theme page
freitagb Nov 14, 2024
8f8f3f5
fix spacing on home page
Nov 14, 2024
43b1a26
Remove duplicate media images
amarouane-ABDELHAK Nov 14, 2024
e24f66e
Remove duplicate media images
amarouane-ABDELHAK Nov 14, 2024
3fcc29a
Set custom width for the carousel grid
dzole0311 Nov 15, 2024
d9c3d33
Update comment
dzole0311 Nov 15, 2024
ae38dee
Replace legacy Fold grid with USWDS grid system
dzole0311 Nov 15, 2024
2d9e9ca
update carousel with HQ proposed text
freitagb Nov 18, 2024
51275bd
Update carousel with HQ proposed text
freitagb Nov 18, 2024
7a99937
Align title on theme page with USWDS
dzole0311 Nov 19, 2024
f9a6849
update rise to change
freitagb Nov 19, 2024
45e3a51
update language on carousel images
Nov 19, 2024
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
32 changes: 16 additions & 16 deletions overrides/home/carousel/items.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
export default [
{
link: 'https://eyes.nasa.gov/apps/earth/#/',
title: 'Eyes on Earth',
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean vitae lorem et neque egestas mollis. Praesent ut porttitor mauris, a sagittis erat",
image: new URL('../media/seaside-background.jpg', import.meta.url).href,
imageAlt: 'Example image alt EIC 2024'
link: 'https://earth.gov/ghgcenter',
title: 'U.S. Greenhouse Gas Center',
description: "The U.S. Greenhouse Gas Center (US GHG Center) is a multi-agency effort consolidating greenhouse gas information from observations and models.",
image: new URL('../media/ghgc.png', import.meta.url).href,
imageAlt: 'Earth with Greenhouse Gas Emissions shaded in red'
},
{
link: 'https://earth.gov/mobile-climate-mapper/',
title: 'Card Title 2',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean vitae lorem et neque egestas mollis. Praesent ut porttitor mauris, a sagittis erat',
image: new URL('../media/swamp.png', import.meta.url).href,
imageAlt: 'Example image alt EIC 2024'
link: 'https://earth.gov/sealevel',
title: 'Global Sea Level Rise',
description: 'The Global Sea Level Rise Portal is an international collaboration that offers essential information on current and project sea level rise to inform coastal communities across the globe.',
image: new URL('../media/global_slr.png', import.meta.url).href,
imageAlt: 'Coastline with crashing waves'
},
{
link: '/stories/agriculture',
title: 'Internal link to the Agriculture story',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean vitae lorem et neque egestas mollis. Praesent ut porttitor mauris, a sagittis erat',
image: new URL('../media/hyperwall-image1.png', import.meta.url).href,
imageAlt: 'Example image alt EIC 2024'
}]
link: 'https://earth.gov/sealevel/us/',
title: 'U.S. Sea Level Rise',
description: 'The U.S. Sea Level Rise portal is a multi-agency effort pairing data visualizations with explanation and science eduction to help communities prepare for challenges that will affect our coastal environments',
image: new URL('../media/us_slr.png', import.meta.url).href,
imageAlt: 'Coastline with crashing waves'
}]
7 changes: 3 additions & 4 deletions overrides/home/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import VisitGHG from "../components/visit-ghg";
import VisitSLR from "../components/visit-slr";
import HyperwallCTA from "../components/hyperwall-cta";
import Partners from "./partners";
import Carousel from './carousel/';
const IntroHeadline = styled(Hug)`

display: flex;
gap: ${glsp(2)};
grid-column: content-start / content-end;
Expand Down Expand Up @@ -107,10 +109,7 @@ export default function HomeComponent() {
</IntroDesc>
</IntroHeadline>
</HomeDescription>
<VisitSLR />
<SpacerDiv/>
<VisitGHG />
<SpacerDiv/>
<Carousel />
<Fold>
<FoldHeader>
<FoldHeadline>
Expand Down
Binary file added overrides/home/media/ghgc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added overrides/home/media/global-slr-no-text.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added overrides/home/media/global_slr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added overrides/home/media/us_slr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stories/components/media/global_slr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stories/components/media/us_slr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions stories/components/slr_carousel/carousel-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from '$veda-ui/react';
import styled from '$veda-ui/styled-components';
import { Button, Icon } from '$veda-ui/@trussworks/react-uswds';

import {
Card,
CardBody,
CardFooter,
} from '$veda-ui/@trussworks/react-uswds';


const progressColor = '#1565EF';

const ProgressIndicator = styled.div`
background-color: ${progressColor};
width: ${props => props.progressWidth}%;
transition: ${props => props.noTransition? null: 'width 200ms ease-out'};
`;

function ProgressBar({ selected, shouldProgress, progressDone, progressPercentage }) {
// If progress is done, 100% - false if something is manually selected
// If it is in progress, progress Percentage - false if something is manually selected
// If it is manually selected, 100%
const progressWidth = progressDone? 100: shouldProgress? progressPercentage: selected? 100: 0;
const noTransition = (!shouldProgress && !progressDone && progressPercentage === 0)? true : false;

return <>
<div className="height-05 bg-base-lighter">
<ProgressIndicator className="height-full" progressWidth={progressWidth} noTransition={noTransition} />
</div>
</>
}

export function ItemPanel({ item, linkComponent: LinkComponent }) {
return (<>

<div className="tablet:margin-top-0 margin-top-2 flex-align-self-stretch">
<p className="margin-top-2 margin-bottom-2 flex-align-self-stretch">{item.description}</p>
<LinkComponent className="display-flex flex-align-center veda-color--link" to={item.link}>
<Icon.ArrowForward stroke={progressColor} fill={progressColor} />
<span className="padding-left-1">Read more</span>
</LinkComponent>
</div>
</>)
}

export default function CarouselItem({ item, itemIdx, onTitleClick, shouldProgress, progressDone, progressPercentage, selected, linkComponent: LinkComponent }) {
return <Card
gridLayout={{ tablet: { col: 6 } }}
containerProps={{className:`hover:bg-base-lightest padding-x-1 radius-0 border-0 animation--transition ${(selected || shouldProgress)? 'opacity-100':'opacity-50'}`}}>
<ProgressBar shouldProgress={shouldProgress} progressDone={progressDone} progressPercentage={progressPercentage}selected={selected} />
<CardBody className="padding-left-0 position-relative">
<h3 className="tablet:margin-top-1 carousel--title text-bold veda-color--base">
{item.title}
</h3>
<p className="margin-top-2 flex-align-self-stretch">{item.description}</p>
<Button
unstyled={true}
className="position-absolute top-0 left-0 width-full height-full blocklink"
onClick={() => { onTitleClick(item); } }
type="button"
role="tab"
aria-label={`Slide ${itemIdx+1}`}
aria-selected={selected.toString()}
aria-controls={`carousel-item-${itemIdx+1}`}
children={undefined} />
</CardBody>
<CardFooter className="padding-left-0 padding-top-1">
<LinkComponent className="display-flex flex-align-center veda-color--link" to={item.link}>
<Icon.ArrowForward stroke={progressColor} fill={progressColor} />
<span className="padding-left-1">Read more</span>
</LinkComponent>
</CardFooter>
</Card>
}
44 changes: 44 additions & 0 deletions stories/components/slr_carousel/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* The classes for css transition group */
.imagetransition {
&-enter {
opacity: 0.5;
}
&-enter-active {
opacity: 1;
transition: opacity 400ms ease-in;
}
&-exit {
opacity: 1;
}
/* ending EXIT animation */
&-exit-active {
opacity: 0;
transition: opacity 400ms ease-out;
}
}

.veda-color--link {
color: var(--veda-color-link);
}
.veda-color--base {
color: var(--veda-color-base);
}

.animation--transition {
transition: opacity 200ms ease-out;
}

.carousel {
&--height {
height: 500px;
}

&--content-image {
width: 100%;
height: 100%;
object-fit: cover;
}
&--title {
font-size: 1.25rem;
}
}
114 changes: 114 additions & 0 deletions stories/components/slr_carousel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, { useState, useEffect, useCallback } from '$veda-ui/react';

import { CSSTransition, TransitionGroup } from "react-transition-group";
import { useMediaQuery } from "$veda-ui-scripts/utils/use-media-query";
import { GridContainer, Grid } from '$veda-ui/@trussworks/react-uswds';
import LazyLoad from '$veda-ui/react-lazyload';
import { CardGroup } from '$veda-ui/@trussworks/react-uswds';

import CarouselItems from './items';
import CarouselItem, { ItemPanel } from './carousel-item';


import SmartLink from '$veda-ui-scripts/components/common/smart-link';

import '/common/styles.scss';
import './index.scss';

const interval = 100;
const slide_length = 50;
const item_n = CarouselItems.length;

export function DesktopCarousel () {
const [timer, setTimer] = useState(0);
const [selectedItem, setSelectedItem] = useState(null);
const [timerAnimationId, setTimerAnimationId] = useState(null);

// Animation starts on landing, once it is stopped, it is not going to be played again.
useEffect(() => {
const intervalId = setInterval(() => {
setTimer(prev => {
return prev + 1;
});
}, interval);
setTimerAnimationId(intervalId);
return () => {
clearInterval(intervalId);
};
}, []);

const animationTimer = timer % slide_length;
// animationTimer/slide_length will never be 1, compensating the value here
const progressPercentage = Math.floor((animationTimer/slide_length) * (100*(slide_length/(slide_length-1))));
const currentProgressItemIdx = Math.floor((timer / slide_length)%item_n);
const itemInProgress = selectedItem?? CarouselItems[currentProgressItemIdx];

const onTitleClick = useCallback((clickedItem) => {
clearInterval(timerAnimationId);
setTimerAnimationId(null);
setSelectedItem(clickedItem);
},[timerAnimationId]);


return (
<GridContainer aria-roledescription="carousel" aria-label="Highlighted VEDA Dashboard projects">
<Grid row className="position-relative carousel--height" aria-live="off">
<TransitionGroup>
<CSSTransition
key={itemInProgress.title}
timeout={2000}
classNames="imagetransition"
>
<div className="carousel--height width-full position-absolute left-0 top-0 shadow-1">
<img className="carousel--content-image" src={itemInProgress.image} alt={itemInProgress.imageAlt} />
</div>
</CSSTransition>
</TransitionGroup>
</Grid>
<CardGroup className="tablet:margin-top-4 margin-top-2" role="tablist" aria-label="Slides">
{CarouselItems.map((item, itemIdx) => {
return <CarouselItem
key={item.title}
item={item}
itemIdx={itemIdx}
onTitleClick={onTitleClick}
progressDone= {selectedItem? false: itemIdx < currentProgressItemIdx}
shouldProgress = {selectedItem? false: currentProgressItemIdx == itemIdx}
selected={!timerAnimationId && selectedItem?.title === item.title}
progressPercentage = {progressPercentage}
linkComponent={SmartLink}
/>
})}
</CardGroup>
</GridContainer>)
}

function TabletCarousel() {
return <GridContainer>
<Grid row className="margin-top-2">
{CarouselItems.map((item) => {
return <Grid col={12} key={item.title} className="margin-bottom-4">
<div>
<img className="carousel--content-image" src={item.image} />
</div>
<h3 className="margin-top-1">{item.title}</h3>
<ItemPanel item={item} linkComponent={SmartLink} />
</Grid>
})}
</Grid>
</GridContainer>
}


export default function SLRCarousel() {
const { isMediumUp } = useMediaQuery();
return isMediumUp?
<LazyLoad
className="hug-reset-container"
offset={100}
once
>
<DesktopCarousel />
</LazyLoad>:
<div className="hug-reset-container"><TabletCarousel /></div>
}
15 changes: 15 additions & 0 deletions stories/components/slr_carousel/items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default [
{
link: 'https://earth.gov/sealevel',
title: 'Global Sea Level Rise',
description: 'The Global Sea Level Rise Portal is an international collaboration that offers essential information on current and project sea level rise to inform coastal communities across the globe.',
image: new URL('../media/global_slr.png', import.meta.url).href,
imageAlt: 'Coastline with crashing waves'
},
{
link: 'https://earth.gov/sealevel/us',
j08lue marked this conversation as resolved.
Show resolved Hide resolved
title: 'U.S. Sea Level Rise',
description: ' The U.S. Sea Level Rise portal is a multi-agency effort pairing data visualizations with explanation and science eduction to help communities prepare for challenges that will affect our coastal environments.',
image: new URL('../media/us_slr.png', import.meta.url).href,
imageAlt: 'Coastline with crashing waves'
}]
16 changes: 10 additions & 6 deletions stories/theme.SLR.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ taxonomy:
- sea level rise
---

import SLRCarousel from './components/slr_carousel/';

import CardGallery from "./components/card_gallery";
import { seaLevelRiseStoryIds } from "../overrides/common/story-data";
import VisitSLR from "../overrides/components/visit-slr";

import Carousel from "../overrides/common/embedded-video-carousel";
import contentArray from './theme.SLR.introduction_sea_level_rise/carousel_content.json';

<Block type="wide">
<Figure>
<VisitSLR />
</Figure>

<Block>
<Prose>
## Visit the Sea Level Rise portals
</Prose>
</Block>


<SLRCarousel />

<Block>
<Prose>
## Info
Expand Down
Loading