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'
44import { useTranslation } from 'components/hooks/useTranslation'
55import { ArticleCard } from './ArticleCard'
6- import { ActionList , ActionMenu } from '@primer/react'
76import { ItemInput } from '@primer/react/lib/deprecated/ActionList/List'
87
9- const PAGE_SIZE = 9
108export 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}
0 commit comments