Skip to content

Commit

Permalink
feat(KUI-1149): add "show more" feature for item with long content in…
Browse files Browse the repository at this point in the history
… Round info grid.
  • Loading branch information
Karl Andin committed Aug 20, 2024
1 parent 2e663d1 commit aca5d1d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 2 deletions.
4 changes: 4 additions & 0 deletions i18n/messages.en.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ module.exports = {
menu_panel_close: 'Close',
menu_panel_menu: 'Menu',
},
showMoreContent: {
show: 'Show more',
hide: 'Hide',
},
bankIdAlertText: `Please note that <a href="https://www.kth.se/en/studies/freestanding-courses/applying-to-a-course-if-you-are-not-in-sweden-1.1275545" class="external-link" target="_blank" rel="noopener noreferrer">Students not located in Sweden may have problems attending a course at KTH.</a> <br/> You could meet obstacles if you're required to pay fees or if you do not have a Swedish Mobile BankID. `,
courseLabels: {
label_course_description: 'Introduction to course',
Expand Down
4 changes: 4 additions & 0 deletions i18n/messages.se.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ module.exports = {
menu_panel_close: 'Stäng',
menu_panel_menu: 'Meny',
},
showMoreContent: {
show: 'Visa mer',
hide: 'Dölj',
},
bankIdAlertText:
'Du behöver ett KTH-konto för att läsa en kurs på KTH, kontot aktiveras med Mobilt BankID eller genom att besöka KTH:s campus. Det enda sättet att starta en kurs utan att besöka campus, är om du har Mobilt BankID.',
courseLabels: {
Expand Down
36 changes: 36 additions & 0 deletions public/css/kursinfo-web.scss
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,42 @@
margin-bottom: 1.5rem;
}

.roundInformation__infoGridItem {
display: flex;
flex-direction: column;

.roundInformation__infoGridItemContent {
position: relative;
overflow: hidden;
max-height: 96px;
transition: max-height 200ms ease-in;

&.hidden::after {
content: '';
position: absolute;
bottom: 0;
height: 24px;
width: 100%;
background: linear-gradient(to bottom, transparent, var(--color-background-alt));
display: block;
}
}

.roundInformation__infoGridItemShowMoreButton {
background-color: transparent;
border: none;
padding: 0;
margin-top: 4px;
color: var(--color-tertiary);
cursor: pointer;
align-self: flex-end;

&:hover {
text-decoration: underline;
}
}
}

.kth-alert {
background-color: var(--color-background);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
import React from 'react'
import React, { useEffect, useState, useRef } from 'react'
import { useLanguage } from '../../hooks/useLanguage'
import InfoModal from '../InfoModal'
import { CourseMemoLink } from './CourseMemoLink'
import { CourseScheduleLink } from './CourseScheduleLink'
import { PlannedModules } from './PlannedModules'

// Calculates if a "Show more" button should be displayed, and creates props for content and button elements.
const useShowMoreContent = content => {
const ref = useRef(null)
const [hasMoreContent, setHasMoreContent] = useState(false)
const [contentHeight, setHeight] = useState(undefined)
const { translation } = useLanguage()

const showMoreContent = hasMoreContent && !!contentHeight
const hideMoreContent = hasMoreContent && !showMoreContent
useEffect(() => {
if (ref.current) {
const el = ref.current
const isOverflowing = el.clientHeight < el.scrollHeight
setHasMoreContent(isOverflowing)
}
}, [content])

const contentProps = {
ref,
style: { maxHeight: contentHeight }, // set max height for animation from the max value specified in css to actual content height
className: `roundInformation__infoGridItemContent ${hideMoreContent ? 'hidden' : ''}`,
}

const showMoreButtonProps = hasMoreContent
? {
onClick: () => {
setHeight(showMoreContent ? undefined : ref.current.scrollHeight)
},
children: showMoreContent ? translation.showMoreContent.hide : translation.showMoreContent.show,
className: 'roundInformation__infoGridItemShowMoreButton',
}
: undefined

return { contentProps, showMoreButtonProps }
}

const Item = ({ children, html, title, infoModalContent }) => {
const { translation } = useLanguage()
const { contentProps, showMoreButtonProps } = useShowMoreContent(html ?? children)

return (
<div>
Expand All @@ -21,7 +58,14 @@ const Item = ({ children, html, title, infoModalContent }) => {
/>
)}
</dt>
{html ? <dd dangerouslySetInnerHTML={{ __html: html }} /> : <dd>{children}</dd>}
<dd className="roundInformation__infoGridItem">
{html ? (
<div {...contentProps} dangerouslySetInnerHTML={{ __html: html }} />
) : (
<div {...contentProps}>{children}</div>
)}
{showMoreButtonProps && <button {...showMoreButtonProps} />}
</dd>
</div>
)
}
Expand Down

0 comments on commit aca5d1d

Please sign in to comment.