Skip to content

Commit efe9997

Browse files
authored
A11y: guides, learning track, and landings (github#40936)
1 parent ef68c71 commit efe9997

File tree

15 files changed

+58
-327
lines changed

15 files changed

+58
-327
lines changed

components/ui/TruncateLines/TruncateLines.module.scss

Lines changed: 0 additions & 7 deletions
This file was deleted.

components/ui/TruncateLines/TruncateLines.tsx

Lines changed: 0 additions & 20 deletions
This file was deleted.

components/ui/TruncateLines/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 4 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,17 @@
1-
import React, { useEffect, useRef, useState } from 'react'
1+
import React, { useRef } from 'react'
22

3-
import { ArticleGuide, useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
3+
import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
44
import { useTranslation } from 'components/hooks/useTranslation'
55
import { ArticleCard } from './ArticleCard'
6-
import { ActionList, ActionMenu } from '@primer/react'
76
import { ItemInput } from '@primer/react/lib/deprecated/ActionList/List'
87

9-
const PAGE_SIZE = 9
108
export const ArticleCards = () => {
119
const { t } = useTranslation('product_guides')
1210
const guideTypes: Record<string, string> = t('guide_types')
1311
const { allTopics, includeGuides } = useProductGuidesContext()
14-
const [numVisible, setNumVisible] = useState(PAGE_SIZE)
15-
const [typeFilter, setTypeFilter] = useState<ItemInput | undefined>()
16-
const [topicFilter, setTopicFilter] = useState<ItemInput | undefined>()
17-
const [filteredResults, setFilteredResults] = useState<Array<ArticleGuide>>([])
18-
const typesRef = useRef<HTMLDivElement>(null)
19-
const topicsRef = useRef<HTMLDivElement>(null)
2012
const articleCardRef = useRef<HTMLUListElement>(null)
2113

22-
useEffect(() => {
23-
setNumVisible(PAGE_SIZE)
24-
setFilteredResults(
25-
(includeGuides || []).filter((card) => {
26-
const matchesType = card.type === typeFilter?.key
27-
const matchesTopic = card.topics.some((key) => key === topicFilter?.key)
28-
return (typeFilter?.key ? matchesType : true) && (topicFilter?.key ? matchesTopic : true)
29-
}),
30-
)
31-
}, [typeFilter, topicFilter])
32-
33-
const clickDropdown = (e: React.RefObject<HTMLDivElement>) => {
34-
if (e === typesRef && typesRef.current) typesRef.current.focus()
35-
if (e === topicsRef && topicsRef.current) topicsRef.current.focus()
36-
}
37-
38-
const loadMore = () => {
39-
if (articleCardRef.current) {
40-
const childListLength = articleCardRef.current.childElementCount
41-
// Leading semi-colon due to prettier to prevent possible ASI failures
42-
// Need to explicitly type assert as HTMLDivElement as focus property missing from dom type definitions for Element.
43-
;(articleCardRef.current.childNodes.item(childListLength - 1) as HTMLDivElement).focus()
44-
}
45-
setNumVisible(numVisible + PAGE_SIZE)
46-
}
47-
48-
const isUserFiltering = typeFilter !== undefined || topicFilter !== undefined
49-
50-
const guides = isUserFiltering ? filteredResults : includeGuides || []
14+
const guides = includeGuides || []
5115

5216
const types = Object.entries(guideTypes).map(([key, val]) => {
5317
return { text: val, key }
@@ -64,65 +28,6 @@ export const ArticleCards = () => {
6428
return (
6529
<div>
6630
<div data-search="hide">
67-
<label htmlFor="guide-filter-form">{t('filter_instructions')}</label>
68-
<form name="guide-filter-form" className="mt-2 mb-5 d-flex d-flex">
69-
<div data-testid="card-filter-types">
70-
<div
71-
onClick={() => clickDropdown(typesRef)}
72-
onKeyDown={() => clickDropdown(typesRef)}
73-
role="button"
74-
tabIndex={-1}
75-
className="text-uppercase f6 color-fg-muted d-block"
76-
>
77-
{t('filters.type')}
78-
</div>
79-
<ActionMenu anchorRef={typesRef}>
80-
<ActionMenu.Button>
81-
{typeFilter ? typeFilter.text : t('filters.all')}
82-
</ActionMenu.Button>
83-
<ActionMenu.Overlay aria-label="types" data-testid="types-dropdown">
84-
<ActionList selectionVariant="single">
85-
{types.map((type) => {
86-
return (
87-
<ActionList.Item onSelect={() => setTypeFilter(type)} key={type.text}>
88-
{type.text}
89-
</ActionList.Item>
90-
)
91-
})}
92-
</ActionList>
93-
</ActionMenu.Overlay>
94-
</ActionMenu>
95-
</div>
96-
97-
<div data-testid="card-filter-topics" className="mx-4">
98-
<div
99-
onClick={() => clickDropdown(topicsRef)}
100-
onKeyDown={() => clickDropdown(topicsRef)}
101-
role="button"
102-
tabIndex={-1}
103-
className="text-uppercase f6 color-fg-muted d-block"
104-
>
105-
{t('filters.topic')}
106-
</div>
107-
<ActionMenu anchorRef={topicsRef}>
108-
<ActionMenu.Button>
109-
{topicFilter ? topicFilter.text : t('filters.all')}
110-
</ActionMenu.Button>
111-
<ActionMenu.Overlay aria-label="topics" data-testid="topics-dropdown">
112-
<ActionList selectionVariant="single">
113-
{topics.map((topic) => {
114-
return (
115-
<ActionList.Item onSelect={() => setTopicFilter(topic)} key={topic.text}>
116-
{topic.text}
117-
</ActionList.Item>
118-
)
119-
})}
120-
</ActionList>
121-
</ActionMenu.Overlay>
122-
</ActionMenu>
123-
</div>
124-
</form>
125-
12631
<div role="status" className="color-fg-muted">
12732
{guides.length === 0
12833
? t('guides_found.none')
@@ -137,7 +42,7 @@ export const ArticleCards = () => {
13742
ref={articleCardRef}
13843
className="d-flex flex-wrap mr-0 mr-md-n6 mr-lg-n8"
13944
>
140-
{guides.slice(0, numVisible).map((card, i) => {
45+
{guides.map((card, i) => {
14146
return (
14247
<ArticleCard
14348
tabIndex={-1}
@@ -148,16 +53,6 @@ export const ArticleCards = () => {
14853
)
14954
})}
15055
</ul>
151-
152-
{guides.length > numVisible && (
153-
<button
154-
className="col-12 mt-5 text-center text-bold color-fg-accent btn-link"
155-
data-search="hide"
156-
onClick={loadMore}
157-
>
158-
{t('load_more')}
159-
</button>
160-
)}
16156
</div>
16257
)
16358
}

src/landings/components/ArticleList.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Link } from 'components/Link'
66
import { ArrowRightIcon } from '@primer/octicons-react'
77
import { FeaturedLink } from 'src/landings/components/ProductLandingContext'
88
import { useMainContext } from 'components/context/MainContext'
9-
import { TruncateLines } from 'components/ui/TruncateLines'
109
import { BumpLink } from 'components/ui/BumpLink'
1110

1211
export type ArticleListPropsT = {
@@ -73,9 +72,9 @@ export const ArticleList = ({
7372
}
7473
>
7574
{link.intro && (
76-
<TruncateLines as="p" maxLines={2} className="color-fg-muted mb-0 mt-1">
77-
<span data-testid="link-with-intro-intro">{link.intro}</span>
78-
</TruncateLines>
75+
<p className="color-fg-muted mb-0 mt-1" data-testid="link-with-intro-intro">
76+
{link.intro}
77+
</p>
7978
)}
8079
{link.date && (
8180
<time
Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
import { useState } from 'react'
2-
import { ArrowRightIcon } from '@primer/octicons-react'
3-
41
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
5-
import { useTranslation } from 'components/hooks/useTranslation'
62
import { RepoCard } from 'src/landings/components/RepoCard'
73

84
export const CommunityExamples = () => {
95
const { productCommunityExamples } = useProductLandingContext()
10-
const { t } = useTranslation('product_landing')
11-
const [numVisible, setNumVisible] = useState(6)
126

137
if (!productCommunityExamples) {
148
return null
@@ -17,22 +11,14 @@ export const CommunityExamples = () => {
1711
return (
1812
<div>
1913
<div className="d-flex flex-wrap gutter">
20-
{productCommunityExamples.slice(0, numVisible).map((repo) => {
14+
{productCommunityExamples.map((repo) => {
2115
return (
2216
<div key={repo.repo} className="col-12 col-xl-4 col-lg-6 mb-4">
2317
<RepoCard repo={repo} />
2418
</div>
2519
)
2620
})}
2721
</div>
28-
{numVisible < productCommunityExamples.length && (
29-
<button
30-
className="btn btn-outline float-right"
31-
onClick={() => setNumVisible(productCommunityExamples.length)}
32-
>
33-
{t('show_more')} <ArrowRightIcon />
34-
</button>
35-
)}
3622
</div>
3723
)
3824
}

src/landings/components/LandingSection.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ type Props = {
1111
export const LandingSection = ({ title, children, className, sectionLink, description }: Props) => {
1212
return (
1313
<div className={cx('container-xl px-3 px-md-6 mt-6', className)}>
14-
{title && (
15-
<HeadingLink as="h2" slug={sectionLink} className="mb-4">
16-
{title}
17-
</HeadingLink>
18-
)}
19-
{description && (
20-
<div className="color-fg-muted f4" dangerouslySetInnerHTML={{ __html: description }} />
21-
)}
14+
<div className="mb-4">
15+
{title && (
16+
<HeadingLink as="h2" slug={sectionLink}>
17+
{title}
18+
</HeadingLink>
19+
)}
20+
{description && (
21+
<div className="color-fg-muted f4" dangerouslySetInnerHTML={{ __html: description }} />
22+
)}
23+
</div>
2224
{children}
2325
</div>
2426
)

src/landings/components/ProductArticlesList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const ProductTreeNodeList = ({ treeNode }: { treeNode: ProductTreeNode }) => {
4646
},
4747
}}
4848
>
49-
<Link className="d-block width-full" href={childNode.href}>
49+
<Link className="d-block width-full text-underline" href={childNode.href}>
5050
{childNode.title}
5151
{childNode.childPages.length > 0 ? (
5252
<small className="color-fg-muted d-inline-block">

src/landings/components/RepoCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const RepoCard = ({ repo, href }: Props) => {
1919
/>
2020
</div>
2121
<div className="flex-auto">
22-
<h4>{repo.repo}</h4>
22+
<h3>{repo.repo}</h3>
2323
<p className="mt-1 color-fg-muted">{repo.description}</p>
2424
</div>
2525
</a>
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import { ArrowRightIcon } from '@primer/octicons-react'
2-
3-
import { Link } from 'components/Link'
41
import { useProductLandingContext } from 'src/landings/components/ProductLandingContext'
5-
import { useTranslation } from 'components/hooks/useTranslation'
62
import { UserCard } from 'src/landings/components/UserCard'
73

84
export const SponsorsExamples = () => {
95
const { productUserExamples } = useProductLandingContext()
10-
const { t } = useTranslation('product_landing')
116

127
if (!productUserExamples) {
138
return null
@@ -16,17 +11,14 @@ export const SponsorsExamples = () => {
1611
return (
1712
<div>
1813
<div className="d-flex flex-wrap gutter">
19-
{productUserExamples.slice(0, 6).map((user) => {
14+
{productUserExamples.map((user) => {
2015
return (
2116
<div key={user.username} className="col-12 col-xl-4 col-lg-6 mb-4">
2217
<UserCard href={`https://github.com/sponsors/${user.username}`} user={user} />
2318
</div>
2419
)
2520
})}
2621
</div>
27-
<Link href={`https://github.com/sponsors/community`} className="btn btn-outline float-right">
28-
{t('explore_people_and_projects')} <ArrowRightIcon />
29-
</Link>
3022
</div>
3123
)
3224
}

0 commit comments

Comments
 (0)