Skip to content

Commit

Permalink
Merge pull request #151 from NASA-IMPACT/develop
Browse files Browse the repository at this point in the history
Merge updated link to global sea level rise portal
  • Loading branch information
amarouane-ABDELHAK authored Nov 12, 2024
2 parents 19e3edb + f651d93 commit d494446
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 386 deletions.
39 changes: 39 additions & 0 deletions common/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.blocklink {
&:focus { outline: none; }
&:focus-visible { outline: 1px solid var(--veda-color-link);}
@supports not selector(:focus-visible) {
&:focus {
outline: 1px solid var(--veda-color-link);
}
}
}

.hug-reset-container {
grid-column: 1 / -1;
}

.card-shadow__hover {
box-shadow: 0 0 2px 0 rgba(44,62,80,0.08),0 6px 6px 0 rgba(44,62,80,0.08);
transition: all 0.24s ease-in-out 0s;
&:hover {
transform: translate(0, 0.125rem);
}
}

.card-image__blend {
mix-blend-mode: multiply;
}

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

// font-size: 20px (1.25rem) will be deprecated with USWDS design system
// but we need a temporary style class for the consistency across the pages

.font-size-md-deprecated {
font-size: calc(1rem + var(--base-text-increment, 0rem));
}
4 changes: 2 additions & 2 deletions overrides/components/visit-slr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ export default function VisitSLR({
<InfoImageContent>
<div>
<StyledVarHeading size="small" as="h2">
U.S. Sea Level Change
Global Sea Level Change
</StyledVarHeading>
<span>
Rising Seas, Changing Coasts
Sea Level is Rising, Worldwide
</span>
<Button
forwardedAs="a"
Expand Down
75 changes: 75 additions & 0 deletions overrides/home/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: 4 } }}
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 overrides/home/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 overrides/home/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 Carousel() {
const { isMediumUp } = useMediaQuery();
return isMediumUp?
<LazyLoad
className="hug-reset-container"
offset={100}
once
>
<DesktopCarousel />
</LazyLoad>:
<div className="hug-reset-container"><TabletCarousel /></div>
}
22 changes: 22 additions & 0 deletions overrides/home/carousel/items.js
Original file line number Diff line number Diff line change
@@ -0,0 +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/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: '/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'
}]
10 changes: 4 additions & 6 deletions overrides/home/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import { Button } from "$veda-ui/@devseed-ui/button";
import Hug from "$veda-ui-scripts/styles/hug";
import {
Fold,
FoldHeader,
FoldTitle,
FoldBody,
FoldHeader, FoldBody,
FoldHeadline,
FoldHeadActions,
FoldHeadActions
} from "$veda-ui-scripts/components/common/fold";
import { StyledVarHeading } from "../common/style";
import { variableGlsp } from "$veda-ui-scripts/styles/variable-utils";
Expand All @@ -31,7 +29,7 @@ const IntroHeadline = styled(Hug)`
${media.mediumDown`
flex-flow: column;
`}
p {
font-size: 1.25rem;
padding-top: 1rem;
Expand Down Expand Up @@ -77,7 +75,7 @@ const CollaboratorsContent = styled.div`
`
const SpacerDiv = styled.div`
padding:2rem;
`
export default function HomeComponent() {
const description =
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"$veda-ui-scripts": "./.veda/ui/app/scripts"
},
"dependencies": {
"pure-react-carousel": "^1.30.1"
"pure-react-carousel": "^1.30.1",
"react-dom": "^18.3.1",
"react-transition-group": "^4.4.5"
}
}
Loading

0 comments on commit d494446

Please sign in to comment.