make journey track cards clickable with hover effect (#58544)
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
.learningTracks {
|
||||
.journeyTracks {
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.trackCard {
|
||||
border: 1px solid
|
||||
var(--borderColor-default, var(--color-border-default, #d1d9e0));
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
padding-bottom: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 1rem;
|
||||
box-shadow:
|
||||
0px 1px 3px 0px rgba(31, 35, 40, 0.08),
|
||||
0px 1px 0px 0px rgba(31, 35, 40, 0.06);
|
||||
@@ -15,6 +16,24 @@
|
||||
--bgColor-default,
|
||||
var(--color-canvas-default, #ffffff)
|
||||
);
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
// journey card hover effect only when the card is not expanded
|
||||
&:not([open]):hover {
|
||||
box-shadow:
|
||||
0 0.25rem 0.5rem 0 rgba(31, 35, 40, 0.12),
|
||||
0 0.125rem 0.25rem 0 rgba(31, 35, 40, 0.08);
|
||||
transform: translateY(-2px);
|
||||
background-color: var(--bgColor-muted, var(--color-canvas-subtle));
|
||||
}
|
||||
}
|
||||
|
||||
.trackSummary {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 1.5rem 1.5rem 1.75rem 1.5rem;
|
||||
}
|
||||
|
||||
.trackHeader {
|
||||
@@ -26,25 +45,25 @@
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.anchorLink {
|
||||
color: var(--fgColor-default, var(--color-fg-default, #1f2328));
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.trackDescription {
|
||||
margin: 0 0 1rem 0;
|
||||
margin: 0;
|
||||
padding-right: 2rem;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: var(--fgColor-muted, var(--color-fg-muted, #656d76));
|
||||
}
|
||||
}
|
||||
|
||||
.expandButton {
|
||||
top: 0;
|
||||
right: 0;
|
||||
top: 1.5rem;
|
||||
right: 1.5rem;
|
||||
}
|
||||
|
||||
.trackGuides {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
padding-left: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0 1.5rem 0.75rem 1.5rem;
|
||||
list-style: none;
|
||||
counter-reset: guide-counter;
|
||||
}
|
||||
@@ -76,11 +95,6 @@
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.guideLink {
|
||||
color: var(--fgColor-accent, var(--color-accent-fg, #0969da));
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Hide only the timeline line that extends below the last badge, preserve everything else */
|
||||
.timelineContainer :global(.Timeline-Item:last-child::before) {
|
||||
background: linear-gradient(
|
||||
@@ -189,21 +203,20 @@
|
||||
}
|
||||
|
||||
.mobileItem .mobileTile {
|
||||
border: 1px solid
|
||||
var(--borderColor-default, var(--color-border-default, #d1d9e0));
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
text-align: left;
|
||||
box-shadow:
|
||||
0px 1px 3px 0px rgba(31, 35, 40, 0.08),
|
||||
0px 1px 0px 0px rgba(31, 35, 40, 0.06);
|
||||
position: relative;
|
||||
|
||||
.trackCard {
|
||||
z-index: 3;
|
||||
background-color: var(
|
||||
--bgColor-default,
|
||||
var(--color-canvas-default, #ffffff)
|
||||
);
|
||||
}
|
||||
|
||||
.trackSummary {
|
||||
padding: 1rem 1rem 1.75rem 1rem;
|
||||
}
|
||||
|
||||
.trackGuides {
|
||||
padding: 0 1rem 0.75rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop: show Timeline component */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* filepath: /workspaces/docs-internal/src/landings/components/journey/JourneyLearningTracks.tsx */
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@primer/octicons-react'
|
||||
import { Button, Details, Timeline, Token, useDetails } from '@primer/react'
|
||||
import { Details, Timeline, Token, useDetails } from '@primer/react'
|
||||
import { Link } from '@/frame/components/Link'
|
||||
import { JourneyTrack } from '@/journeys/lib/journey-path-resolver'
|
||||
import styles from './JourneyLearningTracks.module.scss'
|
||||
@@ -14,40 +14,38 @@ export const JourneyLearningTracks = ({ tracks }: JourneyLearningTracksProps) =>
|
||||
return null
|
||||
}
|
||||
|
||||
const renderTrackContent = (track: JourneyTrack, trackIndex: number) => {
|
||||
const renderTrackContent = (track: JourneyTrack) => {
|
||||
const { getDetailsProps, open } = useDetails({})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Details
|
||||
{...getDetailsProps()}
|
||||
id={`track-${track.id}`}
|
||||
className={styles.trackCard}
|
||||
data-testid="journey-track"
|
||||
>
|
||||
<summary className={styles.trackSummary}>
|
||||
<div className={styles.trackHeader}>
|
||||
<h3 className="h4 text-bold">{track.title}</h3>
|
||||
<Token text={`${track.guides?.length || 0} articles`} />
|
||||
</div>
|
||||
<p className={styles.trackDescription}>{track.description}</p>
|
||||
<Details {...getDetailsProps()}>
|
||||
<Button
|
||||
as="summary"
|
||||
variant="invisible"
|
||||
className={`position-absolute ${styles.expandButton}`}
|
||||
aria-label={
|
||||
open
|
||||
? `Collapse article list ${trackIndex + 1}`
|
||||
: `Expand article list ${trackIndex + 1}`
|
||||
}
|
||||
>
|
||||
<div className={styles.trackDescription}>
|
||||
<p>{track.description}</p>
|
||||
</div>
|
||||
<div className={`position-absolute ${styles.expandButton}`}>
|
||||
{open ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
||||
</Button>
|
||||
</div>
|
||||
</summary>
|
||||
<ol className={styles.trackGuides} data-testid="journey-articles">
|
||||
{(track.guides || []).map((article: { href: string; title: string }) => (
|
||||
<li key={article.title}>
|
||||
<Link href={article.href} className={`text-semibold ${styles.guideLink}`}>
|
||||
<Link href={article.href} className="text-semibold">
|
||||
{article.title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</Details>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -60,10 +58,8 @@ export const JourneyLearningTracks = ({ tracks }: JourneyLearningTracksProps) =>
|
||||
return (
|
||||
<Timeline.Item key={track.id}>
|
||||
<Timeline.Badge className={styles.timelineBadge}>{trackIndex + 1}</Timeline.Badge>
|
||||
<Timeline.Body className={styles.learningTracks}>
|
||||
<div className="position-relative" data-testid="journey-track">
|
||||
{renderTrackContent(track, trackIndex)}
|
||||
</div>
|
||||
<Timeline.Body className={styles.journeyTracks}>
|
||||
{renderTrackContent(track)}
|
||||
</Timeline.Body>
|
||||
</Timeline.Item>
|
||||
)
|
||||
@@ -76,11 +72,7 @@ export const JourneyLearningTracks = ({ tracks }: JourneyLearningTracksProps) =>
|
||||
{tracks.map((track, trackIndex) => (
|
||||
<div key={track.id} className={styles.mobileItem}>
|
||||
<div className={styles.mobileBadge}>{trackIndex + 1}</div>
|
||||
<div className={styles.mobileTile}>
|
||||
<div className="position-relative" data-testid="journey-track">
|
||||
{renderTrackContent(track, trackIndex)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.mobileTile}>{renderTrackContent(track)}</div>
|
||||
{trackIndex < tracks.length - 1 && <div className={styles.mobileConnector} />}
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user