MCPcopy Create free account
hub / github.com/github/docs / ArticleCards

Function ArticleCards

components/guides/ArticleCards.tsx:10–159  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

8
9const PAGE_SIZE = 9
10export const ArticleCards = () => {
11 const { t } = useTranslation('product_guides')
12 const guideTypes: Record<string, string> = t('guide_types')
13 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)
20 const articleCardRef = useRef<HTMLUListElement>(null)
21
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 || []
51
52 const types = Object.entries(guideTypes).map(([key, val]) => {
53 return { text: val, key }
54 }) as ItemInput[]
55
56 types.unshift({ text: t('filters.all'), key: undefined })
57
58 const topics = allTopics?.map((topic) => {
59 return { text: topic, key: topic }
60 }) as ItemInput[]
61
62 topics.unshift({ text: t('filters.all'), key: undefined })
63
64 return (
65 <div>
66 <div data-search="hide">
67 <label htmlFor="guide-filter-form">{t('filter_instructions')}</label>

Callers

nothing calls this directly

Calls 3

useTranslationFunction · 0.90
useProductGuidesContextFunction · 0.90
clickDropdownFunction · 0.85

Tested by

no test coverage detected