Skip to content

Commit

Permalink
v2 drawer qa adjustments (#1850)
Browse files Browse the repository at this point in the history
* reduce gap in differing runs table between location and other info

* add colon back in

* if there are paragraph elements in the description, remove the top padding from the first child and bottom padding from the last

* add show more / show less to description

* clamp title lines at 3 instead of 2, even on small cards

* use height fallback for description line clamping, and only use -webkit-line-clamp if it's supported

* align differing runs table header with content

* remove lines prop from Title

* apply line clamp to any children of the card title

* add extra line for stylelint issue somehow missed by pre-commit
  • Loading branch information
gumaerc authored Dec 3, 2024
1 parent 4dee6e0 commit 736b822
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const Story: React.FC<{ item: NewsFeedItem; mobile: boolean }> = ({
{item.image.url ? (
<Card.Image src={item.image.url} alt={item.image.alt || ""} />
) : null}
<Card.Title href={item.url} lines={2} style={{ marginBottom: -13 }}>
<Card.Title href={item.url} style={{ marginBottom: -13 }}>
{item.title}
</Card.Title>
<Card.Footer>
Expand Down
30 changes: 14 additions & 16 deletions frontends/ol-components/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,13 @@ const Info = styled.div<{ size?: Size }>`
`

const titleOpts = {
shouldForwardProp: (prop: string) => prop !== "lines" && prop !== "size",
shouldForwardProp: (prop: string) => prop !== "size",
}
const Title = styled(Linkable, titleOpts)<{ lines?: number; size?: Size }>`
const Title = styled(Linkable, titleOpts)<{ size?: Size }>`
text-overflow: ellipsis;
height: ${({ lines, size }) => {
height: ${({ size }) => {
const lineHeightPx = size === "small" ? 18 : 20
lines = lines ?? (size === "small" ? 2 : 3)
return theme.typography.pxToRem(lines * lineHeightPx)
return theme.typography.pxToRem(3 * lineHeightPx)
}};
overflow: hidden;
margin: 0;
Expand All @@ -120,16 +119,16 @@ const Title = styled(Linkable, titleOpts)<{ lines?: number; size?: Size }>`
? { ...theme.typography.subtitle2 }
: { ...theme.typography.subtitle1 }}
${({ lines, size }) => {
lines = lines ?? (size === "small" ? 2 : 3)
return `
@supports (-webkit-line-clamp: ${lines}) {
white-space: initial;
display: -webkit-box;
-webkit-line-clamp: ${lines};
-webkit-box-orient: vertical;
}`
}}
@supports (-webkit-line-clamp: 3) {
white-space: initial;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
> * {
-webkit-line-clamp: 3;
}
}
`

const Footer = styled.span`
Expand Down Expand Up @@ -225,7 +224,6 @@ export type ImageProps = NextImageProps & {
type TitleProps = {
children?: ReactNode
href?: string
lines?: number
style?: CSSProperties
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const DifferingRun = styled.div({
display: "flex",
flexWrap: "wrap",
alignItems: "center",
gap: "16px",
gap: "8px",
padding: "12px",
alignSelf: "stretch",
borderBottom: `1px solid ${theme.custom.colors.lightGray2}`,
Expand All @@ -35,7 +35,7 @@ const DifferingRunHeader = styled.div({
display: "flex",
alignSelf: "stretch",
alignItems: "center",
gap: "16px",
gap: "8px",
padding: "12px",
color: theme.custom.colors.darkGray2,
backgroundColor: theme.custom.colors.lightGray1,
Expand Down Expand Up @@ -120,7 +120,7 @@ const DifferingRunsTable: React.FC<{ resource: LearningResource }> = ({
{run.delivery.filter((d) => d.code === "in_person").length > 0 &&
run.location && (
<DifferingRunLocation>
<strong>Location</strong>
<strong>Location:</strong>
<span>{run.location}</span>
</DifferingRunLocation>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react"
import React, { useCallback, useRef, useState } from "react"
import styled from "@emotion/styled"
import Skeleton from "@mui/material/Skeleton"
import Typography from "@mui/material/Typography"
Expand All @@ -21,6 +21,7 @@ import type { User } from "api/hooks/user"
import { LearningResourceCardProps } from "../LearningResourceCard/LearningResourceCard"
import { CardActionButton } from "../LearningResourceCard/LearningResourceListCard"
import VideoFrame from "./VideoFrame"
import { Link } from "../Link/Link"

const DRAWER_WIDTH = "900px"

Expand Down Expand Up @@ -148,12 +149,39 @@ const Platform = styled.div({
gap: "16px",
})

const DescriptionContainer = styled.div({
display: "flex",
flexDirection: "column",
gap: "4px",
width: "100%",
})

const Description = styled.p({
...theme.typography.body2,
color: theme.custom.colors.black,
margin: 0,
whiteSpace: "pre-wrap",
wordBreak: "break-word",
"p:first-child": {
marginTop: 0,
},
"p:last-child": {
marginBottom: 0,
},
})

const DescriptionCollapsed = styled(Description)({
display: "-webkit-box",
overflow: "hidden",
height: `calc(${theme.typography.body2.lineHeight} * 5)`,
"@supports (-webkit-line-clamp: 5)": {
WebkitLineClamp: 5,
WebkitBoxOrient: "vertical",
},
})

const DescriptionExpanded = styled(Description)({
display: "block",
})

const StyledPlatformLogo = styled(PlatformLogo)({
Expand Down Expand Up @@ -439,6 +467,24 @@ const CallToActionSection = ({
}

const ResourceDescription = ({ resource }: { resource?: LearningResource }) => {
const firstRender = useRef(true)
const clampedOnFirstRender = useRef(false)
const [isClamped, setClamped] = useState(false)
const [isExpanded, setExpanded] = useState(false)
const descriptionRendered = useCallback((node: HTMLDivElement) => {
if (node !== null) {
const clamped = node.scrollHeight > node.clientHeight
setClamped(clamped)
if (firstRender.current) {
firstRender.current = false
clampedOnFirstRender.current = clamped
return
}
}
}, [])
const DescriptionText = isExpanded
? DescriptionExpanded
: DescriptionCollapsed
if (!resource) {
return (
<>
Expand All @@ -452,13 +498,22 @@ const ResourceDescription = ({ resource }: { resource?: LearningResource }) => {
)
}
return (
<Description
/**
* Resource descriptions can contain HTML. They are santiized on the
* backend during ETL. This is safe to render.
*/
dangerouslySetInnerHTML={{ __html: resource.description || "" }}
/>
<DescriptionContainer data-testid="drawer-description-container">
<DescriptionText
data-testid="drawer-description-text"
ref={descriptionRendered}
/**
* Resource descriptions can contain HTML. They are santiized on the
* backend during ETL. This is safe to render.
*/
dangerouslySetInnerHTML={{ __html: resource.description || "" }}
/>
{(isClamped || clampedOnFirstRender.current) && (
<Link color="red" size="small" onClick={() => setExpanded(!isExpanded)}>
{isExpanded ? "Show less" : "Show more"}
</Link>
)}
</DescriptionContainer>
)
}

Expand Down

0 comments on commit 736b822

Please sign in to comment.