-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add carousel to home page (#66)
- Loading branch information
Fran McDade
authored and
Fran McDade
committed
Sep 25, 2024
1 parent
465901f
commit 0123448
Showing
18 changed files
with
440 additions
and
109 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
...nts/Home/components/Section/components/SectionHero/components/Carousel/cards/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { CardProps } from "@databiosphere/findable-ui/lib/components/common/Card/card"; | ||
import * as MDX from "../content"; | ||
|
||
export const CAROUSEL_CARDS: Pick<CardProps, "text">[] = [ | ||
{ | ||
text: MDX.ShareUsageAndJoinAdvisoryPanel({}), | ||
}, | ||
{ | ||
text: MDX.LearnToAnalyzeData({}), | ||
}, | ||
]; |
46 changes: 46 additions & 0 deletions
46
...nts/Home/components/Section/components/SectionHero/components/Carousel/carousel.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
mediaDesktopSmallUp, | ||
mediaTabletUp, | ||
} from "@databiosphere/findable-ui/lib/styles/common/mixins/breakpoints"; | ||
import styled from "@emotion/styled"; | ||
import { Bullets } from "../../../../../../../common/Bullets/bullets"; | ||
import { | ||
CAROUSEL_HEIGHT, | ||
CAROUSEL_HEIGHT_SM, | ||
MAX_CARD_WIDTH, | ||
} from "./common/constants"; | ||
|
||
export const CarouselView = styled.div` | ||
grid-column: 1 / -1; | ||
max-width: ${MAX_CARD_WIDTH}px; | ||
width: 100%; | ||
${mediaDesktopSmallUp} { | ||
grid-column: 7 / -1; | ||
grid-row: 1 / 3; | ||
justify-self: flex-end; | ||
} | ||
`; | ||
|
||
export const Carousel = styled.div` | ||
cursor: grab; | ||
height: ${CAROUSEL_HEIGHT_SM}px; | ||
position: relative; /* Positions CardPositioner. */ | ||
user-select: none; | ||
&:active { | ||
cursor: grabbing; | ||
} | ||
${mediaTabletUp} { | ||
height: ${CAROUSEL_HEIGHT}px; | ||
} | ||
`; | ||
|
||
export const StyledBullets = styled(Bullets)` | ||
bottom: 14px; | ||
left: 50%; | ||
position: absolute; | ||
transform: translateX(-50%); | ||
z-index: 100; | ||
`; |
29 changes: 29 additions & 0 deletions
29
...omponents/Home/components/Section/components/SectionHero/components/Carousel/carousel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { | ||
Carousel as CarouselCards, | ||
CarouselView, | ||
StyledBullets, | ||
} from "./carousel.styles"; | ||
import { Cards } from "./components/Cards/cards"; | ||
import { useInteractiveCarousel } from "./hooks/useInteractiveCarousel"; | ||
|
||
export const Carousel = (): JSX.Element => { | ||
const { | ||
activeIndex, | ||
interactiveAction, | ||
interactiveCards, | ||
interactiveIndexes, | ||
onSetActiveIndex, | ||
} = useInteractiveCarousel(); | ||
return ( | ||
<CarouselView> | ||
<CarouselCards {...interactiveAction}> | ||
<Cards activeIndex={activeIndex} cards={interactiveCards} /> | ||
<StyledBullets | ||
activeBullet={activeIndex} | ||
bullets={interactiveIndexes} | ||
onBullet={onSetActiveIndex} | ||
/> | ||
</CarouselCards> | ||
</CarouselView> | ||
); | ||
}; |
11 changes: 11 additions & 0 deletions
11
...ts/Home/components/Section/components/SectionHero/components/Carousel/common/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export const CARD_OFFSET_Y = 8; | ||
export const CARD_SCALE_X = 40; | ||
export const MAX_CARD_HEIGHT = 216; | ||
export const MAX_CARD_HEIGHT_SM = 216; | ||
export const MAX_DECK_SIZE = 1; // Currently, deck size is only 1 additional card. | ||
export const MAX_CARD_WIDTH = 504; | ||
export const CAROUSEL_HEIGHT = MAX_CARD_HEIGHT + MAX_DECK_SIZE * CARD_OFFSET_Y; | ||
export const CAROUSEL_HEIGHT_SM = | ||
MAX_CARD_HEIGHT_SM + MAX_DECK_SIZE * CARD_OFFSET_Y; | ||
export const TRANSITION_DELAY = 100; | ||
export const TRANSITION_DURATION = 100; |
77 changes: 77 additions & 0 deletions
77
...onents/Home/components/Section/components/SectionHero/components/Carousel/common/utils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { | ||
CARD_OFFSET_Y, | ||
CARD_SCALE_X, | ||
MAX_CARD_WIDTH, | ||
MAX_DECK_SIZE, | ||
TRANSITION_DELAY, | ||
TRANSITION_DURATION, | ||
} from "./constants"; | ||
|
||
/** | ||
* Returns the carousel card's position in the deck. | ||
* @param index - Card index. | ||
* @param activeIndex - Active index. | ||
* @param lastIndex - Last index. | ||
* @returns card position (position zero to deck size). | ||
*/ | ||
export function getCardPosition( | ||
index: number, | ||
activeIndex: number, | ||
lastIndex: number | ||
): number { | ||
const order = index - activeIndex; | ||
if (order >= 0) return order; | ||
// If the order is negative, stack the card to the end of the deck. | ||
// Grab the last (positive) position in the deck and add the card position (index + 1). | ||
return lastIndex - activeIndex + index + 1; | ||
} | ||
|
||
/** | ||
* Returns the carousel card's x-axis scale. | ||
* @param cardPosition - Card position. | ||
* @returns card x-axis scale. | ||
*/ | ||
export function getCardScaleX(cardPosition: number): string { | ||
if (cardPosition === 0) return "scaleX(1)"; // The active card is scaled to 1. | ||
return `scaleX(${ | ||
(MAX_CARD_WIDTH - cardPosition * CARD_SCALE_X) / MAX_CARD_WIDTH | ||
})`; | ||
} | ||
|
||
/** | ||
* Returns the carousel card's transform scaleX and translateY. | ||
* @param cardPosition - Card position. | ||
* @returns card transform. | ||
*/ | ||
export function getCardTransform(cardPosition: number): string { | ||
return `${getCardScaleX(cardPosition)} ${getCardTranslateY(cardPosition)}`; | ||
} | ||
|
||
/** | ||
* Returns the carousel card's transition. | ||
* @param cardPosition - Card position. | ||
* @returns card transition. | ||
*/ | ||
export function getCardTransition(cardPosition: number): string { | ||
return `all ${TRANSITION_DURATION}ms ease-in-out ${ | ||
cardPosition * TRANSITION_DELAY | ||
}ms, z-index 0ms ${TRANSITION_DELAY}ms`; | ||
} | ||
|
||
/** | ||
* Returns the carousel card's y-axis offset. | ||
* @param cardPosition - Card position. | ||
* @returns y-axis offset. | ||
*/ | ||
export function getCardTranslateY(cardPosition: number): string { | ||
return `translateY(${(MAX_DECK_SIZE - cardPosition) * CARD_OFFSET_Y}px)`; | ||
} | ||
|
||
/** | ||
* Returns the carousel card's z-index. | ||
* @param cardPosition - Card position. | ||
* @returns card z-index. | ||
*/ | ||
export function getCardZIndex(cardPosition: number): number { | ||
return MAX_DECK_SIZE - cardPosition; | ||
} |
92 changes: 92 additions & 0 deletions
92
...nents/Section/components/SectionHero/components/Carousel/components/Cards/cards.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { mediaTabletUp } from "@databiosphere/findable-ui/lib/styles/common/mixins/breakpoints"; | ||
import { | ||
inkLight, | ||
smokeMain, | ||
} from "@databiosphere/findable-ui/lib/styles/common/mixins/colors"; | ||
import { | ||
textBody500, | ||
textBodyLarge500, | ||
textBodySmall4002Lines, | ||
} from "@databiosphere/findable-ui/lib/styles/common/mixins/fonts"; | ||
import { elevation01 } from "@databiosphere/findable-ui/lib/theme/common/shadows"; | ||
import styled from "@emotion/styled"; | ||
import { ButtonBase as MButtonBase, Card as MCard } from "@mui/material"; | ||
import { | ||
MAX_CARD_HEIGHT, | ||
MAX_CARD_HEIGHT_SM, | ||
MAX_CARD_WIDTH, | ||
} from "../../common/constants"; | ||
import { | ||
getCardTransform, | ||
getCardTransition, | ||
getCardZIndex, | ||
} from "../../common/utils"; | ||
|
||
interface Props { | ||
cardPosition: number; | ||
} | ||
|
||
export const CardPositioner = styled("div")<Props>` | ||
display: grid; | ||
height: 100%; | ||
max-height: ${MAX_CARD_HEIGHT_SM}px; | ||
max-width: ${MAX_CARD_WIDTH}px; | ||
position: absolute; | ||
transform: ${({ cardPosition }) => getCardTransform(cardPosition)}; | ||
transition: ${({ cardPosition }) => getCardTransition(cardPosition)}; | ||
width: 100%; | ||
z-index: ${({ cardPosition }) => getCardZIndex(cardPosition)}; | ||
${mediaTabletUp} { | ||
max-height: ${MAX_CARD_HEIGHT}px; | ||
} | ||
`; | ||
|
||
export const Card = styled(MCard)` | ||
border: none; | ||
box-shadow: ${elevation01}, inset 0 0 0 1px ${smokeMain}; | ||
display: flex; | ||
height: 100%; | ||
width: 100%; | ||
` as typeof MCard; | ||
|
||
export const CardSection = styled.div` | ||
display: flex; | ||
flex: 1; | ||
flex-direction: column; | ||
padding: 24px; | ||
`; | ||
|
||
export const CardContent = styled.div` | ||
h1, | ||
h2, | ||
h3 { | ||
${textBodyLarge500}; | ||
margin: 0; | ||
} | ||
p { | ||
${textBodySmall4002Lines}; | ||
color: ${inkLight}; | ||
margin: 8px 0; | ||
&:last-of-type { | ||
margin-bottom: 0; | ||
} | ||
} | ||
`; | ||
|
||
export const CardCallToAction = styled(MButtonBase)` | ||
&.MuiButtonBase-root { | ||
${textBody500}; | ||
color: #28285b; | ||
margin-top: 16px; | ||
text-decoration: underline; | ||
text-decoration-skip-ink: none; | ||
text-underline-position: from-font; | ||
&:hover { | ||
text-decoration: none; | ||
} | ||
} | ||
`; |
32 changes: 32 additions & 0 deletions
32
.../components/Section/components/SectionHero/components/Carousel/components/Cards/cards.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { CardProps } from "@databiosphere/findable-ui/lib/components/common/Card/card"; | ||
import { RoundedPaper } from "@databiosphere/findable-ui/lib/components/common/Paper/paper.styles"; | ||
import { Fragment } from "react"; | ||
import { getCardPosition } from "../../common/utils"; | ||
import { Card, CardContent, CardPositioner, CardSection } from "./cards.styles"; | ||
|
||
export interface CardsProps { | ||
activeIndex: number; | ||
cards: CardProps[]; | ||
} | ||
|
||
export const Cards = ({ activeIndex, cards }: CardsProps): JSX.Element => { | ||
const lastIndex = cards.length - 1; | ||
return ( | ||
<Fragment> | ||
{cards.map(({ text }, c) => { | ||
return ( | ||
<CardPositioner | ||
key={c} | ||
cardPosition={getCardPosition(c, activeIndex, lastIndex)} | ||
> | ||
<Card component={RoundedPaper}> | ||
<CardSection> | ||
<CardContent>{text}</CardContent> | ||
</CardSection> | ||
</Card> | ||
</CardPositioner> | ||
); | ||
})} | ||
</Fragment> | ||
); | ||
}; |
2 changes: 2 additions & 0 deletions
2
...ents/Home/components/Section/components/SectionHero/components/Carousel/content/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default as LearnToAnalyzeData } from "./learnToAnalyzeData.mdx"; | ||
export { default as ShareUsageAndJoinAdvisoryPanel } from "./shareUsageAndJoinAdvisoryPanel.mdx"; |
3 changes: 3 additions & 0 deletions
3
...ction/components/SectionHero/components/Carousel/content/learnToAnalyzeData.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
### Learn how to analyze your data! | ||
|
||
The new BRC-analytics platform will make heavy use of the Galaxy platform for analysis of data. To learn how to use this system or to improve your already existing skills enroll into [Galaxy Academy 2024](https://training.galaxyproject.org/training-material/events/galaxy-academy-2024.html). The Academy is a global online training event that will take place October 7 - 11, 2024. For more information please see [the event page](https://training.galaxyproject.org/training-material/events/galaxy-academy-2024.html). Note that free registration is required. |
11 changes: 11 additions & 0 deletions
11
...ents/SectionHero/components/Carousel/content/shareUsageAndJoinAdvisoryPanel.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
### Share your usage and join our advisory panel. | ||
|
||
BRC Analytics is actively evolving to provide comprehensive data access and analytical tools for all 785 eukaryotic pathogens, host taxa, and vectors previously supported by VEuPathDB.We need your help to improve—share your usage patterns and join our design advisory panel to help shape the future of the platform. | ||
|
||
<CardCTA | ||
href="https://docs.google.com/forms/d/e/1FAIpQLSdSj9QtrY1zdUF45V7zGDKY1qKlo8BbSgF0BPfKfSzRTlgsVg/viewform?usp=sf_link" | ||
rel="noopener noreferrer" | ||
target="_blank" | ||
> | ||
Get Involved | ||
</CardCTA> |
50 changes: 50 additions & 0 deletions
50
...onents/Section/components/SectionHero/components/Carousel/hooks/useInteractiveCarousel.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { CardProps } from "@databiosphere/findable-ui/lib/components/common/Card/card"; | ||
import { useMemo } from "react"; | ||
import { | ||
UseSwipeInteraction, | ||
useSwipeInteraction, | ||
} from "../../../../../../../../../hooks/useSwipeInteraction/useSwipeInteraction"; | ||
import { CAROUSEL_CARDS } from "../cards/constants"; | ||
|
||
export interface UseInteractiveCarousel { | ||
activeIndex: UseSwipeInteraction["activeIndex"]; | ||
interactiveAction?: UseSwipeInteraction["interactiveAction"]; | ||
interactiveCards: CardProps[]; | ||
interactiveIndexes: number[]; | ||
onSetActiveIndex: UseSwipeInteraction["onSetActiveIndex"]; | ||
onSetSwipeAction: UseSwipeInteraction["onSetSwipeAction"]; | ||
} | ||
|
||
/** | ||
* Facilitates interaction capabilities for the carousel. | ||
* @returns carousel cards, interactive indexes, and interactive actions. | ||
*/ | ||
export function useInteractiveCarousel(): UseInteractiveCarousel { | ||
// Raw carousel cards. | ||
const carouselCards = CAROUSEL_CARDS; | ||
// Get the interactive indexes. | ||
const interactiveIndexes = useMemo( | ||
() => buildInteractiveIndexes(carouselCards), | ||
[carouselCards] | ||
); | ||
// Get the active index and interactive actions. | ||
const swipeInteraction = useSwipeInteraction( | ||
interactiveIndexes.length, | ||
true, | ||
8000 | ||
); | ||
return { | ||
interactiveCards: carouselCards, | ||
interactiveIndexes, | ||
...swipeInteraction, | ||
}; | ||
} | ||
|
||
/** | ||
* Returns array of interactive indexes. | ||
* @param cards - Cards. | ||
* @returns a list of indexes that are interactive. | ||
*/ | ||
function buildInteractiveIndexes(cards: CardProps[]): number[] { | ||
return [...Array(cards.length).keys()]; | ||
} |
Oops, something went wrong.