1
0
mirror of synced 2025-12-19 18:10:59 -05:00
Files
docs/components/landing/CodeExamples.tsx
Lucas Costi a7860a720f Change code-example test to not use Actions (#24979)
* Change code-example test to not use Actions

* Use discussions instead

* Use code-security, but make the 'more' test not an exact number

* Removed references to actions/code-examples.yml

* Update tests/browser/browser.js

Co-authored-by: Robert Sese <robert.sese@gmail.com>

Co-authored-by: Martin Lopes <martin389@github.com>
Co-authored-by: Robert Sese <robert.sese@gmail.com>
2022-02-02 22:32:39 -06:00

119 lines
3.7 KiB
TypeScript

import { useEffect, useState } from 'react'
import { ArrowRightIcon, SearchIcon } from '@primer/octicons-react'
import { Text } from '@primer/components'
import { useProductLandingContext } from 'components/context/ProductLandingContext'
import { useTranslation } from 'components/hooks/useTranslation'
import { CodeExampleCard } from 'components/landing/CodeExampleCard'
import { Link } from 'components/Link'
const PAGE_SIZE = 6
export const CodeExamples = () => {
const { productCodeExamples } = useProductLandingContext()
const { t } = useTranslation('product_landing')
const [numVisible, setNumVisible] = useState(PAGE_SIZE)
const [search, setSearch] = useState('')
const [typed, setTyped] = useState('')
useEffect(() => {
setNumVisible(PAGE_SIZE) // reset the visible count (only matters after searching)
}, [search])
const isSearching = !!search
let searchResults: typeof productCodeExamples = []
if (isSearching) {
const matchReg = new RegExp(search, 'i')
searchResults = productCodeExamples.filter((example) => {
const searchableStr = `${example.tags.join(' ')} ${example.title} ${example.description}`
return matchReg.test(searchableStr)
})
}
return (
<div>
<form
className="pr-lg-3 mb-5 mt-3"
onSubmit={(event) => {
event.preventDefault()
setSearch(typed.trim())
}}
>
<Text
className="ml-1 mr-2"
fontWeight="bold"
fontSize={2}
as="label"
htmlFor="searchCodeExamples"
id="searchCodeExamples"
>
Search code examples:
</Text>
<input
data-testid="code-examples-input"
className="input-lg py-2 px-3 col-12 col-lg-8 form-control"
placeholder={t('search_code_examples')}
type="search"
autoComplete="off"
aria-label={t('search_code_examples')}
onChange={(event) => setTyped(event.target.value)}
value={typed}
/>
<button data-testid="code-examples-search-btn" className="btn ml-2 py-2" type="submit">
Search
</button>
</form>
{isSearching && (
<div role="status">
<h3>
{t('search_results_for')}: {search}
</h3>
<p className="mb-4">
{t('matches_displayed')}: {searchResults.length}
</p>
</div>
)}
<ul className="d-flex flex-wrap gutter">
{(isSearching ? searchResults : productCodeExamples.slice(0, numVisible)).map((example) => {
return (
<li key={example.href} className="col-12 col-xl-4 col-lg-6 mb-4 list-style-none">
<CodeExampleCard example={example} />
</li>
)
})}
</ul>
{numVisible < productCodeExamples.length && !isSearching && (
<button
data-testid="code-examples-show-more"
className="btn btn-outline float-right"
onClick={() => setNumVisible(numVisible + PAGE_SIZE)}
>
{t('show_more')} <ArrowRightIcon />
</button>
)}
{isSearching && searchResults.length === 0 && (
<div
role="status"
data-testid="code-examples-no-results"
className="py-4 text-center color-fg-muted"
>
<div className="mb-3">
<SearchIcon size={24} />{' '}
</div>
<h3 className="text-normal">
{t('sorry')} <strong>{search}</strong>
</h3>
<p className="my-3 f4">
{t('no_example')} <br /> {t('try_another')}
</p>
<Link href="https://github.com/github/docs/tree/main/data/product-examples">
{t('learn')} <ArrowRightIcon />
</Link>
</div>
)}
</div>
)
}