| 
1 | 1 | import cx from 'classnames'  | 
2 |  | -import { useState, SyntheticEvent } from 'react'  | 
3 |  | -import { ChevronDownIcon } from '@primer/octicons-react'  | 
4 |  | -import { ActionList } from '@primer/react'  | 
 | 2 | +import { TreeView } from '@primer/react'  | 
5 | 3 | 
 
  | 
6 | 4 | import { Link } from 'components/Link'  | 
7 | 5 | import { ProductTreeNode } from 'components/context/MainContext'  | 
8 | 6 | import { EventType, sendEvent } from 'src/events/browser'  | 
9 |  | -import styles from './SidebarProduct.module.scss'  | 
10 | 7 | 
 
  | 
11 | 8 | type SectionProps = {  | 
12 | 9 |   routePath: string  | 
13 | 10 |   page: ProductTreeNode  | 
14 | 11 |   title: string  | 
15 |  | -  defaultOpen: boolean  | 
16 | 12 | }  | 
17 | 13 | export const ProductCollapsibleSection = (props: SectionProps) => {  | 
18 |  | -  const { routePath, defaultOpen, title, page } = props  | 
19 |  | -  const [isOpen, setIsOpen] = useState(defaultOpen)  | 
20 |  | - | 
21 |  | -  const onToggle = (e: SyntheticEvent) => {  | 
22 |  | -    const newIsOpen = (e.target as HTMLDetailsElement).open  | 
23 |  | -    setIsOpen(newIsOpen)  | 
24 |  | -    sendEvent({  | 
25 |  | -      type: EventType.navigate,  | 
26 |  | -      navigate_label: `details ${newIsOpen ? 'open' : 'close'}: ${title}`,  | 
27 |  | -    })  | 
28 |  | -  }  | 
29 |  | - | 
 | 14 | +  const { routePath, page } = props  | 
30 | 15 |   // The lowest level page link displayed in the tree  | 
31 | 16 |   const renderTerminalPageLink = (page: ProductTreeNode) => {  | 
32 | 17 |     const title = page.shortTitle || page.title  | 
33 |  | - | 
34 | 18 |     const isCurrent = routePath === page.href  | 
 | 19 | + | 
35 | 20 |     return (  | 
36 |  | -      <ActionList.Item  | 
 | 21 | +      <Link  | 
 | 22 | +        href={page.href}  | 
37 | 23 |         key={page.href}  | 
38 |  | -        data-testid="sidebar-article"  | 
39 |  | -        data-is-current-page={isCurrent}  | 
40 |  | -        className={cx(  | 
41 |  | -          'width-full position-relative',  | 
42 |  | -          styles.sidebarArticle,  | 
43 |  | -          isCurrent && ['text-bold', styles.sidebarArticleActive]  | 
44 |  | -        )}  | 
45 |  | -        sx={{  | 
46 |  | -          padding: '2px 0',  | 
47 |  | -          ':hover': {  | 
48 |  | -            borderRadius: 0,  | 
49 |  | -          },  | 
50 |  | -        }}  | 
 | 24 | +        className={cx('color-fg-default no-underline', isCurrent ? 'text-bold' : '')}  | 
51 | 25 |       >  | 
52 |  | -        <Link  | 
53 |  | -          href={page.href}  | 
54 |  | -          className={cx(  | 
55 |  | -            'd-block pl-6 pr-5 py-1 no-underline width-full',  | 
56 |  | -            isCurrent ? 'color-fg-accent' : 'color-fg-default'  | 
57 |  | -          )}  | 
 | 26 | +        <TreeView.Item  | 
 | 27 | +          id={page.href}  | 
 | 28 | +          data-testid="sidebar-article"  | 
 | 29 | +          current={isCurrent}  | 
 | 30 | +          defaultExpanded={isCurrent}  | 
 | 31 | +          onSelect={() => {  | 
 | 32 | +            sendEvent({  | 
 | 33 | +              type: EventType.navigate,  | 
 | 34 | +              navigate_label: `product page navigate to: ${page.href}`,  | 
 | 35 | +            })  | 
 | 36 | +          }}  | 
58 | 37 |         >  | 
59 | 38 |           {title}  | 
60 |  | -        </Link>  | 
61 |  | -      </ActionList.Item>  | 
 | 39 | +        </TreeView.Item>  | 
 | 40 | +      </Link>  | 
62 | 41 |     )  | 
63 | 42 |   }  | 
64 | 43 | 
 
  | 
65 | 44 |   return (  | 
66 |  | -    <details open={defaultOpen} onToggle={onToggle} className="details-reset">  | 
67 |  | -      <summary className="outline-none">  | 
68 |  | -        <div className="d-flex flex-justify-between">  | 
69 |  | -          <div className="pl-4 pr-1 py-2 f5 d-block flex-auto mr-3 color-fg-default no-underline text-bold">  | 
70 |  | -            {title}  | 
71 |  | -          </div>  | 
72 |  | -          <span style={{ marginTop: 7 }} className="flex-shrink-0 pr-3">  | 
73 |  | -            <ChevronDownIcon className={cx('opacity-60', isOpen && 'rotate-180')} />  | 
74 |  | -          </span>  | 
75 |  | -        </div>  | 
76 |  | -      </summary>  | 
77 |  | - | 
78 |  | -      {  | 
 | 45 | +    <>  | 
 | 46 | +      {/* <!-- some pages have nested child pages (formerly known as a mapTopic) --> */}  | 
 | 47 | +      {page.childPages[0]?.documentType === 'mapTopic' ? (  | 
79 | 48 |         <>  | 
80 |  | -          {/* <!-- some pages have nested child pages (formerly known as a mapTopic) --> */}  | 
81 |  | -          {page.childPages[0]?.documentType === 'mapTopic' ? (  | 
82 |  | -            <ul className="list-style-none position-relative">  | 
83 |  | -              {page.childPages.map((childPage, i) => {  | 
84 |  | -                const childTitle = childPage.shortTitle || childPage.title  | 
 | 49 | +          {page.childPages.map((childPage, i) => {  | 
 | 50 | +            const childTitle = childPage.shortTitle || childPage.title  | 
 | 51 | +            const isActive = routePath.includes(childPage.href)  | 
 | 52 | +            const isCurrent = routePath === childPage.href  | 
85 | 53 | 
 
  | 
86 |  | -                const isActive = routePath.includes(childPage.href)  | 
87 |  | -                const isCurrent = routePath === childPage.href  | 
88 |  | - | 
89 |  | -                return (  | 
90 |  | -                  <li key={childPage.href + i} data-is-current-page={isCurrent}>  | 
91 |  | -                    <details  | 
92 |  | -                      open={isActive}  | 
93 |  | -                      onToggle={(e) => e.stopPropagation()}  | 
94 |  | -                      className="details-reset"  | 
95 |  | -                    >  | 
96 |  | -                      <summary>  | 
97 |  | -                        <div className={cx('pl-4 pr-5 py-2 no-underline')}>{childTitle}</div>  | 
98 |  | -                      </summary>  | 
99 |  | -                      <div data-testid="sidebar-article-group" className="pb-0">  | 
100 |  | -                        <ActionList variant="full" className="my-2">  | 
101 |  | -                          {childPage.childPages.map((cp) => {  | 
102 |  | -                            return renderTerminalPageLink(cp)  | 
103 |  | -                          })}  | 
104 |  | -                        </ActionList>  | 
105 |  | -                      </div>  | 
106 |  | -                    </details>  | 
107 |  | -                  </li>  | 
108 |  | -                )  | 
109 |  | -              })}  | 
110 |  | -            </ul>  | 
111 |  | -          ) : page.childPages[0]?.documentType === 'article' ? (  | 
112 |  | -            <div data-testid="sidebar-article-group" className="pb-0">  | 
113 |  | -              <ActionList variant="full" className="my-2">  | 
114 |  | -                {page.childPages.map(renderTerminalPageLink)}  | 
115 |  | -              </ActionList>  | 
116 |  | -            </div>  | 
117 |  | -          ) : null}  | 
 | 54 | +            return (  | 
 | 55 | +              <div key={childPage.href + i}>  | 
 | 56 | +                <TreeView.Item defaultExpanded={isActive} id={childTitle} current={isCurrent}>  | 
 | 57 | +                  {childTitle}  | 
 | 58 | +                  <TreeView.SubTree data-testid="sidebar-article-group">  | 
 | 59 | +                    {childPage.childPages.map((cp) => {  | 
 | 60 | +                      return renderTerminalPageLink(cp)  | 
 | 61 | +                    })}  | 
 | 62 | +                  </TreeView.SubTree>  | 
 | 63 | +                </TreeView.Item>  | 
 | 64 | +              </div>  | 
 | 65 | +            )  | 
 | 66 | +          })}  | 
118 | 67 |         </>  | 
119 |  | -      }  | 
120 |  | -    </details>  | 
 | 68 | +      ) : page.childPages[0]?.documentType === 'article' ? (  | 
 | 69 | +        <div data-testid="sidebar-article-group">  | 
 | 70 | +          {page.childPages.map((cp) => {  | 
 | 71 | +            return renderTerminalPageLink(cp)  | 
 | 72 | +          })}  | 
 | 73 | +        </div>  | 
 | 74 | +      ) : null}  | 
 | 75 | +    </>  | 
121 | 76 |   )  | 
122 | 77 | }  | 
0 commit comments