Skip to content

Commit 70fbdab

Browse files
committed
Improves card layouts and adds sandbox card
Refactors card layouts for better spacing and responsiveness. Introduces a new sandbox card component for displaying sandbox environments. Updates tutorial card list to support compact cards.
1 parent 9707d3a commit 70fbdab

File tree

14 files changed

+190
-111
lines changed

14 files changed

+190
-111
lines changed

src/components/badge/badge.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
--icon-size: 12px;
4444
--line-height: 1.23077;
4545
--min-height: 1.25rem;
46-
--padding-left-right: 0;
46+
--padding-left-right: 5px;
4747
--padding-top-bottom: 1px;
4848
}
4949

src/components/card/card.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
background-color: var(--token-color-surface-primary);
1111
border-radius: var(--card-border-radius);
12-
padding: 8px;
12+
padding: 16px;
1313
width: 100%;
1414

1515
@nest html[data-theme='dark'] & {

src/components/card/components/card-description/card-description.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
.root {
7-
margin-top: 2px;
7+
margin-top: 4px;
88
}
99

1010
.text {

src/components/card/components/card-footer/card-footer.module.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@
44
*/
55

66
.root {
7-
margin-top: 10px;
8-
margin-bottom: 0;
7+
margin-top: 16px;
98
}

src/components/cards-grid-list/components/tutorial-cards-grid-list/index.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,34 @@ import {
1010
TutorialCardWithAuthElements,
1111
} from 'components/tutorial-card'
1212
import s from './tutorial-cards.module.css'
13+
import compactStyles from 'components/tutorial-card/tutorial-card-compact.module.css'
1314

1415
interface TutorialCardsGridListProps extends CardsGridListProps {
1516
tutorials: TutorialCardPropsWithId[]
17+
compact?: boolean
1618
}
1719

18-
/**
19-
* Handles rendering a grid of Tutorial cards, and pre-fetching the
20-
* `isBookmarked` state for each card.
21-
*/
22-
const TutorialCardsGridList = ({ tutorials, ...restProps }) => {
23-
/**
24-
* Collect the `tutorialIds` and React elements to render in separate arrays
25-
* at the same time (to save on iterating over the same data twice).
26-
*/
20+
const TutorialCardsGridList = ({
21+
tutorials,
22+
compact = false,
23+
...restProps
24+
}) => {
2725
const tutorialIds = []
2826
const cardsGridListItems = []
2927
tutorials.forEach((tutorial: TutorialCardPropsWithId) => {
3028
tutorialIds.push(tutorial.id)
3129
cardsGridListItems.push(
32-
<div className={s.sandboxCardBox} key={tutorial.id}>
30+
<div
31+
className={`${s.tutorialCardBox} ${
32+
compact ? compactStyles.compactTutorialCard : ''
33+
}`}
34+
key={tutorial.id}
35+
>
3336
<TutorialCardWithAuthElements {...tutorial} hasBookmark={false} />
3437
</div>
3538
)
3639
})
3740

38-
/**
39-
* Prime the `isBookmarked` queries for the tutorial cards we know we need to
40-
* render via collected `tutorialIds` array.
41-
*/
4241
const { isFetching, isRefetching } = useBookmarksByTutorialIds({
4342
tutorialIds,
4443
})

src/components/cards-grid-list/components/tutorial-cards-grid-list/tutorial-cards.module.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
.sandboxCardBox {
1+
/**
2+
* Copyright (c) HashiCorp, Inc.
3+
* SPDX-License-Identifier: MPL-2.0
4+
*/
5+
6+
.tutorialCardBox {
27
min-height: 100px;
38
height: 100%;
49
display: flex;

src/components/cards-grid-list/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ interface CardsGridListProps {
99
children: ReactNode
1010
isOrdered?: boolean
1111
fixedColumns?: number
12-
gridGap?: '16px' | '24px'
12+
gridGap?: '8px' | '12px' | '16px' | '24px'
1313
}
1414

1515
export type { CardsGridListProps }
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright (c) HashiCorp, Inc.
3+
* SPDX-License-Identifier: MPL-2.0
4+
*/
5+
6+
import React from 'react'
7+
import { ProductSlug } from 'types/products'
8+
import Card from 'components/card'
9+
import CardTitle from 'components/card/components/card-title'
10+
import CardDescription from 'components/card/components/card-description'
11+
import CardFooter from 'components/card/components/card-footer'
12+
import ButtonLink from 'components/button-link'
13+
import ProductIcon from 'components/product-icon'
14+
import s from './sandbox-card.module.css'
15+
16+
export interface SandboxCardProps {
17+
title: string
18+
description: string
19+
labId: string
20+
products: string[]
21+
onLaunch: () => void
22+
className?: string
23+
}
24+
25+
const SandboxCard: React.FC<SandboxCardProps> = ({
26+
title,
27+
description,
28+
labId,
29+
products,
30+
onLaunch,
31+
className,
32+
}) => {
33+
return (
34+
<div className={`${s.sandboxCardWrapper} ${className || ''}`}>
35+
<Card className={s.sandboxCard}>
36+
<div className={s.cardHeader}>
37+
<CardTitle text={title} />
38+
<div className={s.productIcons}>
39+
{products.map((productSlug) => (
40+
<ProductIcon
41+
key={`product-${labId}-${productSlug}`}
42+
productSlug={productSlug as ProductSlug}
43+
size={16}
44+
className={s.productIcon}
45+
/>
46+
))}
47+
</div>
48+
</div>
49+
<CardDescription text={description} className={s.description} />
50+
<CardFooter className={s.footer}>
51+
<ButtonLink
52+
href="#"
53+
className={s.launchButton}
54+
aria-label={`Launch ${title} Sandbox`}
55+
onClick={(e) => {
56+
e.preventDefault()
57+
e.stopPropagation()
58+
onLaunch()
59+
}}
60+
size="medium"
61+
text="Launch Sandbox"
62+
/>
63+
</CardFooter>
64+
</Card>
65+
</div>
66+
)
67+
}
68+
69+
export default SandboxCard
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright (c) HashiCorp, Inc.
3+
* SPDX-License-Identifier: MPL-2.0
4+
*/
5+
6+
.sandboxCardWrapper {
7+
width: 100%;
8+
}
9+
10+
.sandboxCard {
11+
padding: 12px;
12+
}
13+
14+
.cardHeader {
15+
display: flex;
16+
align-items: flex-start;
17+
justify-content: space-between;
18+
gap: 12px;
19+
}
20+
21+
.productIcons {
22+
display: flex;
23+
align-items: center;
24+
gap: 4px;
25+
flex-shrink: 0;
26+
}
27+
28+
.productIcon {
29+
opacity: 0.8;
30+
}
31+
32+
.description {
33+
margin-top: 3px;
34+
}
35+
36+
.footer {
37+
margin-top: 12px;
38+
margin-bottom: 0;
39+
}
40+
41+
.launchButton {
42+
width: 100%;
43+
justify-content: center;
44+
}
45+
46+
@media (max-width: 768px) {
47+
.cardHeader {
48+
flex-direction: column;
49+
align-items: flex-start;
50+
gap: 8px;
51+
}
52+
53+
.productIcons {
54+
align-self: flex-start;
55+
}
56+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (c) HashiCorp, Inc.
3+
* SPDX-License-Identifier: MPL-2.0
4+
*/
5+
6+
.compactTutorialCard {
7+
padding: 12px;
8+
}
9+
10+
.compactDescription {
11+
margin-top: 3px;
12+
}
13+
14+
.compactFooter {
15+
margin-top: 12px;
16+
margin-bottom: 0;
17+
}
18+
19+
.compactBadge {
20+
--padding-left-right: 0;
21+
}

0 commit comments

Comments
 (0)