1
0
mirror of synced 2025-12-21 10:57:10 -05:00
Files
docs/components/article/PlatformPicker.tsx

83 lines
2.9 KiB
TypeScript

import { useEffect, useState } from 'react'
import { useArticleContext } from 'components/context/ArticleContext'
import { parseUserAgent } from 'src/events/components/user-agent'
import { InArticlePicker } from './InArticlePicker'
const platformQueryKey = 'platform'
const platforms = [
{ value: 'mac', label: 'Mac' },
{ value: 'windows', label: 'Windows' },
{ value: 'linux', label: 'Linux' },
]
// Nota bene: platform === os
// Imperatively modify article content to show only the selected platform
// find all platform-specific *block* elements and hide or show as appropriate
// example: {% mac %} block content {% endmac %}
function showPlatformSpecificContent(platform: string) {
const markdowns = Array.from(document.querySelectorAll<HTMLElement>('.ghd-tool'))
markdowns
.filter((el) => platforms.some((platform) => el.classList.contains(platform.value)))
.forEach((el) => {
el.style.display = el.classList.contains(platform) ? '' : 'none'
// hack: special handling for minitoc links -- we can't pass the tool classes
// directly to the Primer NavList.Item generated <li>, it gets passed down
// to the child <a>. So if we find an <a> that has the tool class and its
// parent is an <li>, we hide/unhide that element as well.
if (el.tagName === 'A' && el.parentElement && el.parentElement.tagName === 'LI') {
el.parentElement.style.display = el.classList.contains(platform) ? '' : 'none'
}
})
// find all platform-specific *inline* elements and hide or show as appropriate
// example: <span class="platform-mac">inline content</span>
const platformEls = Array.from(
document.querySelectorAll<HTMLElement>(
platforms.map((platform) => `.platform-${platform.value}`).join(', '),
),
)
platformEls.forEach((el) => {
el.style.display = el.classList.contains(`platform-${platform}`) ? '' : 'none'
})
}
export const PlatformPicker = () => {
const { defaultPlatform, detectedPlatforms } = useArticleContext()
const [defaultUA, setDefaultUA] = useState('')
useEffect(() => {
let userAgent = parseUserAgent().os
if (userAgent === 'ios') {
userAgent = 'mac'
}
setDefaultUA(userAgent)
}, [])
// Defensively, just in case some article happens to have an array
// but for some reasons, it might be empty, let's not have a picker
// at all.
if (!detectedPlatforms.length) return null
const options = platforms.filter((platform) => detectedPlatforms.includes(platform.value))
return (
<InArticlePicker
defaultValue={defaultPlatform}
fallbackValue={
detectedPlatforms.includes(defaultUA)
? defaultUA
: detectedPlatforms[detectedPlatforms.length - 1]
}
cookieKey="osPreferred"
queryStringKey={platformQueryKey}
onValue={showPlatformSpecificContent}
preferenceName="os"
ariaLabel="Platform"
options={options}
/>
)
}