Skip to content

Commit 8222c25

Browse files
authored
Merge pull request #12061 from github/repo-sync
repo sync
2 parents 3d87d03 + a7d99df commit 8222c25

13 files changed

Lines changed: 486 additions & 445 deletions

File tree

components/Search.tsx

Lines changed: 236 additions & 188 deletions
Large diffs are not rendered by default.

components/page-header/Header.tsx

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ export const Header = () => {
1818
const router = useRouter()
1919
const { relativePath, error } = useMainContext()
2020
const { t } = useTranslation(['header', 'homepage'])
21-
const [isMenuOpen, setIsMenuOpen] = useState(false)
21+
const [isMenuOpen, setIsMenuOpen] = useState(
22+
router.pathname !== '/' && router.query.query && true
23+
)
2224
const [scroll, setScroll] = useState(false)
2325

24-
// the graphiql explorer utilizes `?query=` in the url and we don't want our search bar to mess that up
25-
const updateSearchParams = router.asPath !== 'graphql/overview/explorer'
26-
2726
useEffect(() => {
2827
function onScroll() {
2928
setScroll(window.scrollY > 10)
@@ -61,15 +60,15 @@ export const Header = () => {
6160
</div>
6261

6362
<div className="mr-2">
64-
<VersionPicker variant="compact" />
63+
<VersionPicker />
6564
</div>
6665

6766
<LanguagePicker />
6867

6968
{/* <!-- GitHub.com homepage and 404 page has a stylized search; Enterprise homepages do not --> */}
7069
{relativePath !== 'index.md' && error !== '404' && (
7170
<div className="d-inline-block ml-3">
72-
<Search iconSize={16} updateSearchParams={updateSearchParams} isHeaderSearch={true} />
71+
<Search iconSize={16} isHeaderSearch={true} />
7372
</div>
7473
)}
7574
</div>
@@ -107,26 +106,22 @@ export const Header = () => {
107106
<div
108107
className={cx('width-full position-sticky top-0', isMenuOpen ? 'd-block' : 'd-none')}
109108
>
110-
<div className="mt-3 mb-2">
111-
<div className="pt-3 mb-4 ml-2">
112-
<Breadcrumbs />
113-
</div>
114-
<h4 className="f5 text-normal color-fg-muted ml-3">{t('explore_by_product')}</h4>
115-
116-
<ProductPicker />
109+
<div className="my-4">
110+
<Breadcrumbs />
117111
</div>
118112

119-
<div className="border-top my-2 mx-3" />
113+
<ProductPicker />
114+
115+
<div className="border-top my-2" />
120116
<VersionPicker variant="inline" />
121117

122-
{/* <!-- Language picker - 'English', 'Japanese', etc --> */}
123-
<div className="border-top my-2 mx-3" />
118+
<div className="border-top my-2" />
124119
<LanguagePicker variant="inline" />
125120

126121
{/* <!-- GitHub.com homepage and 404 page has a stylized search; Enterprise homepages do not --> */}
127122
{relativePath !== 'index.md' && error !== '404' && (
128-
<div className="my-2 pt-3 mx-3">
129-
<Search iconSize={16} updateSearchParams={updateSearchParams} />
123+
<div className="my-2 pt-3">
124+
<Search iconSize={16} isMobileSearch={true} />
130125
</div>
131126
)}
132127
</div>
Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,41 @@
11
import { useRouter } from 'next/router'
2-
import { Box, Dropdown, Details, Text, useDetails } from '@primer/components'
3-
import { ChevronDownIcon } from '@primer/octicons-react'
4-
52
import { Link } from 'components/Link'
63
import { useLanguages } from 'components/context/LanguagesContext'
4+
import { Picker } from 'components/ui/Picker'
75

86
type Props = {
97
variant?: 'inline'
108
}
9+
1110
export const LanguagePicker = ({ variant }: Props) => {
1211
const router = useRouter()
1312
const { languages } = useLanguages()
14-
const { getDetailsProps, setOpen } = useDetails({ closeOnOutsideClick: true })
1513
const locale = router.locale || 'en'
1614
const langs = Object.values(languages)
1715
const selectedLang = languages[locale]
1816

19-
if (variant === 'inline') {
20-
return (
21-
<Details {...getDetailsProps()} data-testid="language-picker">
22-
<summary
23-
className="d-block btn btn-invisible color-fg-default"
24-
aria-label="Toggle language list"
25-
>
26-
<div className="d-flex flex-items-center flex-justify-between">
27-
<Text>{selectedLang.nativeName || selectedLang.name}</Text>
28-
<ChevronDownIcon size={24} className="arrow ml-md-1" />
29-
</div>
30-
</summary>
31-
<Box mt={1}>
32-
{langs.map((lang) => {
33-
if (lang.wip) {
34-
return null
35-
}
36-
37-
return (
38-
<Dropdown.Item onClick={() => setOpen(false)} key={lang.code}>
39-
<Link href={router.asPath} locale={lang.code}>
40-
{lang.nativeName ? (
41-
<>
42-
{lang.nativeName} ({lang.name})
43-
</>
44-
) : (
45-
lang.name
46-
)}
47-
</Link>
48-
</Dropdown.Item>
49-
)
50-
})}
51-
</Box>
52-
</Details>
53-
)
54-
}
55-
5617
return (
57-
<Details {...getDetailsProps()} data-testid="language-picker" className="position-relative">
58-
<summary className="d-block btn btn-invisible color-fg-default">
59-
<Text>{selectedLang.nativeName || selectedLang.name}</Text>
60-
<Dropdown.Caret />
61-
</summary>
62-
<Dropdown.Menu direction="sw" style={{ width: 'unset' }}>
63-
{langs.map((lang) => {
64-
if (lang.wip) {
65-
return null
66-
}
67-
68-
return (
69-
<Dropdown.Item key={lang.code} onClick={() => setOpen(false)}>
70-
<Link href={router.asPath} locale={lang.code}>
71-
{lang.nativeName ? (
72-
<>
73-
{lang.nativeName} ({lang.name})
74-
</>
75-
) : (
76-
lang.name
77-
)}
78-
</Link>
79-
</Dropdown.Item>
80-
)
81-
})}
82-
</Dropdown.Menu>
83-
</Details>
18+
<Picker
19+
variant={variant}
20+
data-testid="language-picker"
21+
defaultText="Choose language"
22+
options={langs
23+
.filter((lang) => !lang.wip)
24+
.map((lang) => ({
25+
text: lang.nativeName || lang.name,
26+
selected: lang === selectedLang,
27+
item: (
28+
<Link href={router.asPath} locale={lang.code}>
29+
{lang.nativeName ? (
30+
<>
31+
{lang.nativeName} ({lang.name})
32+
</>
33+
) : (
34+
lang.name
35+
)}
36+
</Link>
37+
),
38+
}))}
39+
/>
8440
)
8541
}

components/page-header/ProductPicker.tsx

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,33 @@ import { useRouter } from 'next/router'
22

33
import { Link } from 'components/Link'
44
import { useMainContext } from 'components/context/MainContext'
5-
import { ChevronDownIcon, LinkExternalIcon } from '@primer/octicons-react'
6-
import { Box, Dropdown, Details, useDetails } from '@primer/components'
5+
import { LinkExternalIcon } from '@primer/octicons-react'
6+
import { Picker } from 'components/ui/Picker'
77

8-
// Product Picker - GitHub.com, Enterprise Server, etc
98
export const ProductPicker = () => {
109
const router = useRouter()
1110
const { activeProducts, currentProduct } = useMainContext()
12-
const { getDetailsProps, setOpen } = useDetails({ closeOnOutsideClick: true })
1311

1412
return (
15-
<Details {...getDetailsProps()} className="details-reset">
16-
<summary
17-
className="d-block color-fg-default btn btn-invisible"
18-
role="button"
19-
aria-label="Toggle products list"
20-
>
21-
<div
22-
data-testid="current-product"
23-
data-current-product-path={currentProduct?.href}
24-
className="d-flex flex-items-center flex-justify-between"
25-
>
26-
<span>{currentProduct?.name || 'All Products'}</span>
27-
<ChevronDownIcon size={24} className="arrow ml-md-1" />
28-
</div>
29-
</summary>
30-
<Box data-testid="product-picker-list" py="2" style={{ zIndex: 6 }}>
31-
{activeProducts.map((product) => {
32-
return (
33-
<Dropdown.Item key={product.id} onClick={() => setOpen(false)}>
34-
<Link href={`${product.external ? '' : `/${router.locale}`}${product.href}`}>
35-
{product.name}
36-
{product.external && (
37-
<span className="ml-1">
38-
<LinkExternalIcon size="small" />
39-
</span>
40-
)}
41-
</Link>
42-
</Dropdown.Item>
43-
)
44-
})}
45-
</Box>
46-
</Details>
13+
<Picker
14+
variant="inline"
15+
data-testid="product-picker"
16+
data-current-product-path={currentProduct?.href}
17+
defaultText="All products"
18+
options={activeProducts.map((product) => ({
19+
text: product.name,
20+
selected: product === currentProduct,
21+
item: (
22+
<Link href={`${product.external ? '' : `/${router.locale}`}${product.href}`}>
23+
{product.name}
24+
{product.external && (
25+
<span className="ml-1">
26+
<LinkExternalIcon size="small" />
27+
</span>
28+
)}
29+
</Link>
30+
),
31+
}))}
32+
/>
4733
)
4834
}
Lines changed: 29 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,52 @@
11
import { useRouter } from 'next/router'
2-
import cx from 'classnames'
3-
import { Dropdown, Details, Box, Text, useDetails } from '@primer/components'
4-
import { ArrowRightIcon, ChevronDownIcon } from '@primer/octicons-react'
2+
import { ArrowRightIcon } from '@primer/octicons-react'
53

64
import { Link } from 'components/Link'
75
import { useMainContext } from 'components/context/MainContext'
86
import { useVersion } from 'components/hooks/useVersion'
97
import { useTranslation } from 'components/hooks/useTranslation'
8+
import { Picker } from 'components/ui/Picker'
109

1110
type Props = {
12-
variant?: 'inline' | 'compact'
11+
variant?: 'inline'
1312
}
13+
1414
export const VersionPicker = ({ variant }: Props) => {
1515
const router = useRouter()
1616
const { currentVersion } = useVersion()
1717
const { allVersions, page, enterpriseServerVersions } = useMainContext()
18-
const { getDetailsProps, setOpen } = useDetails({ closeOnOutsideClick: true })
1918
const { t } = useTranslation('pages')
2019

2120
if (page.permalinks && page.permalinks.length <= 1) {
2221
return null
2322
}
2423

2524
return (
26-
<>
27-
<div>
28-
<Details
29-
{...getDetailsProps()}
30-
className={cx(
31-
'position-relative details-reset',
32-
variant === 'inline' ? 'd-block' : 'd-inline-block'
33-
)}
34-
data-testid="article-version-picker"
35-
>
36-
<summary
37-
className="d-block btn btn-invisible color-fg-default"
38-
aria-haspopup="true"
39-
aria-label="Toggle version list"
40-
>
41-
{variant === 'inline' ? (
42-
<div className="d-flex flex-items-center flex-justify-between">
43-
<Text>{allVersions[currentVersion].versionTitle}</Text>
44-
<ChevronDownIcon size={24} className="arrow ml-md-1" />
45-
</div>
46-
) : (
47-
<>
48-
<Text>{allVersions[currentVersion].versionTitle}</Text>
49-
<Dropdown.Caret />
50-
</>
51-
)}
52-
</summary>
53-
{variant === 'inline' ? (
54-
<Box py="2">
55-
{(page.permalinks || []).map((permalink) => {
56-
return (
57-
<Dropdown.Item key={permalink.href} onClick={() => setOpen(false)}>
58-
<Link href={permalink.href}>{permalink.pageVersionTitle}</Link>
59-
</Dropdown.Item>
60-
)
61-
})}
62-
<Box mt={1}>
63-
<Link
64-
onClick={() => {
65-
setOpen(false)
66-
}}
67-
href={`/${router.locale}/${enterpriseServerVersions[0]}/admin/all-releases`}
68-
className="f6 no-underline color-fg-muted pl-3 pr-2 no-wrap"
69-
>
70-
{t('all_enterprise_releases')}{' '}
71-
<ArrowRightIcon verticalAlign="middle" size={15} className="mr-2" />
72-
</Link>
73-
</Box>
74-
</Box>
75-
) : (
76-
<Dropdown.Menu direction="sw" style={{ width: 'unset' }}>
77-
{(page.permalinks || []).map((permalink) => {
78-
return (
79-
<Dropdown.Item key={permalink.href} onClick={() => setOpen(false)}>
80-
<Link href={permalink.href}>{permalink.pageVersionTitle}</Link>
81-
</Dropdown.Item>
82-
)
83-
})}
84-
<Box
85-
borderColor="border.default"
86-
borderTopWidth={1}
87-
borderTopStyle="solid"
88-
mt={2}
89-
pt={2}
90-
pb={1}
25+
<Picker
26+
variant={variant}
27+
data-testid="version-picker"
28+
defaultText="Choose version"
29+
options={(page.permalinks || [])
30+
.map((permalink) => ({
31+
text: permalink.pageVersionTitle,
32+
selected: allVersions[currentVersion].versionTitle === permalink.pageVersionTitle,
33+
item: <Link href={permalink.href}>{permalink.pageVersionTitle}</Link>,
34+
}))
35+
.concat([
36+
{
37+
text: t('all_enterprise_releases'),
38+
selected: false,
39+
item: (
40+
<Link
41+
href={`/${router.locale}/${enterpriseServerVersions[0]}/admin/all-releases`}
42+
className="f6 no-underline color-fg-muted"
9143
>
92-
<Link
93-
onClick={() => {
94-
setOpen(false)
95-
}}
96-
href={`/${router.locale}/${enterpriseServerVersions[0]}/admin/all-releases`}
97-
className="f6 no-underline color-fg-muted pl-3 pr-2 no-wrap"
98-
>
99-
{t('all_enterprise_releases')}{' '}
100-
<ArrowRightIcon verticalAlign="middle" size={15} className="mr-2" />
101-
</Link>
102-
</Box>
103-
</Dropdown.Menu>
104-
)}
105-
</Details>
106-
</div>
107-
</>
44+
{t('all_enterprise_releases')}{' '}
45+
<ArrowRightIcon verticalAlign="middle" size={15} className="mr-2" />
46+
</Link>
47+
),
48+
},
49+
])}
50+
/>
10851
)
10952
}

0 commit comments

Comments
 (0)