Skip to content

Commit 98293d9

Browse files
authored
Homepage Stories & Events layout fixes (#1103)
* Pass slot props to Card. Adjust css to align and match designs * Remove date label and abbreviate month for small variant cards * Default size to medium
1 parent 180d5ce commit 98293d9

File tree

3 files changed

+66
-37
lines changed

3 files changed

+66
-37
lines changed

frontends/mit-open/src/pages/HomePage/NewsEventsSection.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ const EventsContainer = styled.section`
7373
flex-direction: column;
7474
align-items: flex-start;
7575
gap: 12px;
76-
align-self: stretch;
7776
`
7877

7978
const StoryCard = styled(Card)<{ mobile: boolean }>`
@@ -145,8 +144,6 @@ const EventMonth = styled.p`
145144
`
146145

147146
const EventTitle = styled.p`
148-
height: ${theme.typography.pxToRem(59)};
149-
align-self: stretch;
150147
color: ${theme.custom.colors.darkGray2};
151148
${{ ...theme.typography.subtitle1 }}
152149
margin: 0;
@@ -176,7 +173,9 @@ const Story: React.FC<{ item: NewsFeedItem; mobile: boolean }> = ({
176173
return (
177174
<StoryCard mobile={mobile} href={item.url}>
178175
<Card.Image src={item.image?.url} alt={item.image?.alt} />
179-
<Card.Title>{item.title}</Card.Title>
176+
<Card.Title lines={2} style={{ marginBottom: -13 }}>
177+
{item.title}
178+
</Card.Title>
180179
<Card.Footer>
181180
Published: {formatDate(item.news_details?.publish_date)}
182181
</Card.Footer>
@@ -258,7 +257,7 @@ const NewsEventsSection: React.FC = () => {
258257
<Content>
259258
<StoriesContainer>
260259
<Typography variant="h4">Stories</Typography>
261-
<Grid container columnSpacing="24px" rowSpacing="29px">
260+
<Grid container columnSpacing="24px" rowSpacing="28px">
262261
{stories.map((item) => (
263262
<Grid item key={item.id} xs={12} sm={12} md={6} lg={4} xl={4}>
264263
<Story item={item as NewsFeedItem} mobile={false} />

frontends/ol-components/src/components/Card/Card.tsx

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, {
44
Children,
55
ImgHTMLAttributes,
66
isValidElement,
7+
CSSProperties,
78
} from "react"
89
import styled from "@emotion/styled"
910
import { theme } from "../ThemeProvider/ThemeProvider"
@@ -81,22 +82,31 @@ const Info = styled.div<{ size?: Size }>`
8182
margin-bottom: ${({ size }) => (size === "small" ? 4 : 8)}px;
8283
`
8384

84-
const Title = styled.h3<{ size?: Size }>`
85+
const Title = styled.h3<{ lines?: number; size?: Size }>`
8586
text-overflow: ellipsis;
86-
height: ${({ size }) => theme.typography.pxToRem(size === "small" ? 36 : 60)};
87+
height: ${({ lines, size }) => {
88+
const lineHeightPx = size === "small" ? 18 : 20
89+
lines = lines ?? (size === "small" ? 2 : 3)
90+
return theme.typography.pxToRem(lines * lineHeightPx)
91+
}};
8792
overflow: hidden;
8893
margin: 0;
8994
9095
${({ size }) =>
9196
size === "small"
9297
? { ...theme.typography.subtitle2 }
9398
: { ...theme.typography.subtitle1 }}
94-
@supports (-webkit-line-clamp: ${({ size }) => (size === "small" ? 2 : 3)}) {
95-
white-space: initial;
96-
display: -webkit-box;
97-
-webkit-line-clamp: ${({ size }) => (size === "small" ? 2 : 3)};
98-
-webkit-box-orient: vertical;
99-
}
99+
100+
${({ lines, size }) => {
101+
lines = lines ?? (size === "small" ? 2 : 3)
102+
return `
103+
@supports (-webkit-line-clamp: ${lines}) {
104+
white-space: initial;
105+
display: -webkit-box;
106+
-webkit-line-clamp: ${lines};
107+
-webkit-box-orient: vertical;
108+
}`
109+
}}
100110
`
101111

102112
const Footer = styled.span`
@@ -134,17 +144,34 @@ type CardProps = {
134144
size?: Size
135145
href?: string
136146
}
147+
148+
type ImageProps = ImgHTMLAttributes<HTMLImageElement> & {
149+
size?: Size
150+
style?: CSSProperties
151+
}
152+
type TitleProps = {
153+
children?: ReactNode
154+
lines?: number
155+
style?: CSSProperties
156+
}
157+
type SlotProps = { children?: ReactNode; style?: CSSProperties }
158+
137159
type Card = FC<CardProps> & {
138160
Content: FC<{ children: ReactNode }>
139-
Image: FC<ImgHTMLAttributes<HTMLImageElement> | { size?: Size }>
140-
Info: FC<{ children: ReactNode }>
141-
Title: FC<{ children: ReactNode; size?: Size }>
142-
Footer: FC<{ children: ReactNode }>
143-
Actions: FC<{ children: ReactNode }>
161+
Image: FC<ImageProps>
162+
Info: FC<SlotProps>
163+
Title: FC<TitleProps>
164+
Footer: FC<SlotProps>
165+
Actions: FC<SlotProps>
144166
}
145167

146168
const Card: Card = ({ children, className, size, href }) => {
147-
let content, imageProps, info, title, footer, actions
169+
let content,
170+
image: ImageProps = {},
171+
info: SlotProps = {},
172+
title: TitleProps = {},
173+
footer: SlotProps = {},
174+
actions: SlotProps = {}
148175

149176
const _Container = href ? LinkContainer : Container
150177

@@ -164,11 +191,11 @@ const Card: Card = ({ children, className, size, href }) => {
164191
Children.forEach(children, (child) => {
165192
if (!isValidElement(child)) return
166193
if (child.type === Content) content = child.props.children
167-
else if (child.type === Image) imageProps = child.props
168-
else if (child.type === Info) info = child.props.children
169-
else if (child.type === Title) title = child.props.children
170-
else if (child.type === Footer) footer = child.props.children
171-
else if (child.type === Actions) actions = child.props.children
194+
else if (child.type === Image) image = child.props
195+
else if (child.type === Info) info = child.props
196+
else if (child.type === Title) title = child.props
197+
else if (child.type === Footer) footer = child.props
198+
else if (child.type === Actions) actions = child.props
172199
})
173200

174201
if (content) {
@@ -184,21 +211,27 @@ const Card: Card = ({ children, className, size, href }) => {
184211
return (
185212
<Wrapper className={className} size={size}>
186213
<_Container to={href!}>
187-
{imageProps && (
214+
{image && (
188215
<Image
189216
size={size}
190-
{...(imageProps as ImgHTMLAttributes<HTMLImageElement>)}
217+
{...(image as ImgHTMLAttributes<HTMLImageElement>)}
191218
/>
192219
)}
193220
<Body>
194-
{info && <Info size={size}>{info}</Info>}
195-
<Title size={size}>{title}</Title>
221+
{info.children && (
222+
<Info size={size} {...info}>
223+
{info.children}
224+
</Info>
225+
)}
226+
<Title size={size} {...title}>
227+
{title.children}
228+
</Title>
196229
</Body>
197230
<Bottom>
198-
<Footer>{footer}</Footer>
231+
<Footer {...footer}>{footer.children}</Footer>
199232
</Bottom>
200233
</_Container>
201-
{actions && <Actions>{actions}</Actions>}
234+
{actions.children && <Actions {...actions}>{actions.children}</Actions>}
202235
</Wrapper>
203236
)
204237
}

frontends/ol-components/src/components/LearningResourceCard/LearningResourceCard.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const isOcw = (resource: LearningResource) =>
7373
resource.resource_type === ResourceTypeEnum.Course &&
7474
resource.platform?.code === PlatformEnum.Ocw
7575

76-
const getStartDate = (resource: LearningResource) => {
76+
const getStartDate = (resource: LearningResource, size: Size = "medium") => {
7777
let startDate = resource.next_start_date
7878

7979
if (!startDate) {
@@ -87,7 +87,7 @@ const getStartDate = (resource: LearningResource) => {
8787

8888
if (!startDate) return null
8989

90-
return formatDate(startDate, "MMMM DD, YYYY")
90+
return formatDate(startDate, `MMM${size === "medium" ? "M" : ""} DD, YYYY`)
9191
}
9292

9393
const StartDate: React.FC<{ resource: LearningResource; size?: Size }> = ({
@@ -98,11 +98,8 @@ const StartDate: React.FC<{ resource: LearningResource; size?: Size }> = ({
9898

9999
if (!startDate) return null
100100

101-
const label = isOcw(resource)
102-
? size === "medium"
103-
? "As taught in:"
104-
: ""
105-
: "Starts:"
101+
const label =
102+
size === "medium" ? (isOcw(resource) ? "As taught in:" : "Starts:") : ""
106103

107104
return (
108105
<>

0 commit comments

Comments
 (0)