Skip to content

Commit 58ff4b4

Browse files
authored
A11y: remove horizontal scroll (#39170)
1 parent b4152c7 commit 58ff4b4

File tree

20 files changed

+22
-215
lines changed

20 files changed

+22
-215
lines changed

components/ui/MarkdownContent/stylesheets/code.scss

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
border: 1px var(--color-border-default) solid;
66
}
77

8+
pre code {
9+
white-space: pre-wrap;
10+
}
11+
812
[class~="height-constrained-code-block"] pre {
913
max-height: 32rem;
10-
overflow: auto;
14+
overflow-y: auto;
1115
}
1216

1317
[class~="code-example"] {

data/learning-tracks/README.md

-5
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ Learning track data for a product is defined in two places:
2323
2424
For example, in `data/learning-tracks/actions.yml`, each of the items from the content file's `learningTracks` array is represented with additional data such as `title`, `description`, and an array of `guides` links.
2525
26-
One learning track in this YAML **per version** must be designated as a "featured" learning track via `featured_track: true`, which will set it to appear at the top of the product guides page. A test will fail if this property is missing.
27-
28-
The `featured_track` property can be a simple boolean (i.e., `featured_track: true`) or it can be a string that includes versioning statements (e.g., `featured_track: '{% ifversion fpt %}true{% else %}false{% endif %}'`). If you use versioning, you'll have multiple `featured_track`s per YML file, but make sure that only one will render in each currently supported version. A test will fail if there are more or less than one featured link for each version.
29-
3026
## Versioning
3127
3228
Versioning for learning tracks is processed at page render time. The code lives in [`lib/learning-tracks.js`](lib/learning-tracks.js), which is called by `page.render()`. The processed learning tracks are then rendered by `components/guides`.
@@ -41,7 +37,6 @@ For example:
4137
learning_track_name:
4238
title: 'Learning track title'
4339
description: 'Learning track description'
44-
featured_track: true
4540
versions:
4641
ghes: '>=3.0'
4742
guides:

data/learning-tracks/actions.yml

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ getting_started:
1010
- /actions/using-workflows/about-workflows
1111
- /actions/using-workflows/reusing-workflows
1212
- /actions/security-guides/security-hardening-for-github-actions
13-
featured_track: true
1413
adopting_github_actions_for_your_enterprise_ghec:
1514
title: Adopt GitHub Actions for your enterprise
1615
description: >-

data/learning-tracks/admin.yml

-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ get_started_with_github_ae:
33
description: >-
44
Learn about {% data variables.product.prodname_ghe_managed %} and complete
55
the initial configuration of a new enterprise.
6-
featured_track: true
76
versions:
87
ghae: '*'
98
guides:
@@ -20,7 +19,6 @@ deploy_an_instance:
2019
description: >-
2120
Install {% data variables.product.prodname_ghe_server %} on your platform of
2221
choice and configure SAML authentication.
23-
featured_track: true
2422
versions:
2523
ghes: '*'
2624
guides:

data/learning-tracks/code-security.yml

-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ security_advisories:
33
description: >-
44
Using repository security advisories to privately fix a reported
55
vulnerability and get a CVE.
6-
featured_track: '{% ifversion fpt or ghec %}true{% else %}false{% endif %}'
76
guides:
87
- >-
98
/code-security/security-advisories/guidance-on-reporting-and-writing/about-coordinated-disclosure-of-security-vulnerabilities
@@ -174,7 +173,6 @@ code_security_actions:
174173
description: >-
175174
Check your default branch and every pull request to keep vulnerabilities and
176175
errors out of your repository.
177-
featured_track: '{% ifversion ghae or ghes %}true{% else %}false{% endif %}'
178176
guides:
179177
- >-
180178
/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning

lib/page.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,7 @@ class Page {
208208

209209
// Learning tracks may contain Liquid and need to have versioning processed.
210210
if (this.rawLearningTracks) {
211-
const { featuredTrack, learningTracks } = await processLearningTracks(
212-
this.rawLearningTracks,
213-
context,
214-
)
215-
this.featuredTrack = featuredTrack
211+
const { learningTracks } = await processLearningTracks(this.rawLearningTracks, context)
216212
this.learningTracks = learningTracks
217213
}
218214

src/content-linter/lib/learning-tracks-schema.js

-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ export default {
2626
type: 'array',
2727
items: { type: 'string' },
2828
},
29-
featured_track: {
30-
type: ['boolean', 'string'],
31-
},
3229
versions: versionsProps,
3330
},
3431
},

src/content-linter/tests/lint-files.js

+1-45
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,13 @@ import { frontmatter, deprecatedProperties } from '../../../lib/frontmatter.js'
1818
import languages from '../../../lib/languages.js'
1919
import releaseNotesSchema from '../lib/release-notes-schema.js'
2020
import learningTracksSchema from '../lib/learning-tracks-schema.js'
21-
import { renderContent, liquid } from '#src/content-render/index.js'
22-
import getApplicableVersions from '../../../lib/get-applicable-versions.js'
23-
import { allVersions } from '../../../lib/all-versions.js'
21+
import { liquid } from '#src/content-render/index.js'
2422
import { getDiffFiles } from '../lib/diff-files.js'
2523
import { formatAjvErrors } from '../../../tests/helpers/schemas.js'
2624

2725
jest.useFakeTimers({ legacyFakeTimers: true })
2826

2927
const __dirname = path.dirname(fileURLToPath(import.meta.url))
30-
const enterpriseServerVersions = Object.keys(allVersions).filter((v) =>
31-
v.startsWith('enterprise-server@'),
32-
)
3328

3429
const rootDir = path.join(__dirname, '../../..')
3530
const contentDir = path.join(rootDir, 'content')
@@ -1023,45 +1018,6 @@ describe('lint learning tracks', () => {
10231018
expect(valid, errors).toBe(true)
10241019
})
10251020

1026-
it('has one and only one featured track per supported version', async () => {
1027-
// Use the YAML filename to determine which product this refers to, and then peek
1028-
// inside the product TOC frontmatter to see which versions the product is available in.
1029-
const product = path.posix.basename(yamlRelPath, '.yml')
1030-
const productTocPath = path.posix.join('content', product, 'index.md')
1031-
const productContents = await fs.readFile(productTocPath, 'utf8')
1032-
const { data } = frontmatter(productContents)
1033-
const productVersions = getApplicableVersions(data.versions, productTocPath)
1034-
1035-
const featuredTracks = {}
1036-
const context = { enterpriseServerVersions }
1037-
1038-
// For each of the product's versions, render the learning track data and look for a featured track.
1039-
await Promise.all(
1040-
productVersions.map(async (version) => {
1041-
const featuredTracksPerVersion = []
1042-
1043-
for (const entry of Object.values(dictionary)) {
1044-
if (!entry.featured_track) return
1045-
context.currentVersion = version
1046-
context[allVersions[version].shortName] = true
1047-
const isFeaturedLink =
1048-
typeof entry.featured_track === 'boolean' ||
1049-
(await renderContent(entry.featured_track, context, {
1050-
textOnly: true,
1051-
})) === 'true'
1052-
featuredTracksPerVersion.push(isFeaturedLink)
1053-
}
1054-
1055-
featuredTracks[version] = featuredTracksPerVersion.length
1056-
}),
1057-
)
1058-
1059-
Object.entries(featuredTracks).forEach(([version, numOfFeaturedTracks]) => {
1060-
const errorMessage = `Expected 1 featured learning track but found ${numOfFeaturedTracks} for ${version} in ${yamlAbsPath}`
1061-
expect(numOfFeaturedTracks, errorMessage).toBe(1)
1062-
})
1063-
})
1064-
10651021
it('contains valid liquid', () => {
10661022
const toLint = []
10671023
Object.values(dictionary).forEach(({ title, description }) => {

src/landings/components/GuidesHero.module.scss

-15
This file was deleted.
+3-78
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,17 @@
1-
import cx from 'classnames'
21
import { useProductGuidesContext } from 'src/landings/components/ProductGuidesContext'
3-
import { ArrowRightIcon, StarFillIcon } from '@primer/octicons-react'
4-
import { useTranslation } from 'components/hooks/useTranslation'
5-
import { Link } from 'components/Link'
6-
import { TruncateLines } from 'components/ui/TruncateLines'
72
import { Lead } from 'components/ui/Lead'
8-
import styles from './GuidesHero.module.scss'
93

10-
export const GuidesHero = () => {
11-
const { title, intro, featuredTrack } = useProductGuidesContext()
12-
const { t } = useTranslation('product_guides')
13-
const cardWidth = 280
14-
const firstCardWidth = cardWidth + 10 // so the english text doesn't wrap
15-
16-
const guideItems = featuredTrack?.guides?.map((guide) => (
17-
<li className="px-2 d-flex flex-shrink-0" key={guide.href} style={{ width: cardWidth }}>
18-
<Link
19-
href={`${guide.href}?learn=${featuredTrack.trackName}&learnProduct=${featuredTrack.trackProduct}`}
20-
className="d-inline-block Box p-5 color-bg-default color-border-default no-underline"
21-
>
22-
<div className="d-flex flex-justify-between flex-items-center">
23-
<div
24-
className="color-bg-default color-fg-accent border d-inline-flex flex-items-center flex-justify-center circle"
25-
style={{ width: 40, height: 40 }}
26-
>
27-
{featuredTrack.guides && (
28-
<span className="f2 lh-condensed-ultra text-center text-bold">
29-
{featuredTrack.guides?.indexOf(guide) + 1}
30-
</span>
31-
)}
32-
</div>
33-
<div className="color-fg-muted h6 text-uppercase">
34-
{t('guide_types')[guide.page?.type || '']}
35-
</div>
36-
</div>
37-
<h3 className="text-semibold my-4 color-fg-default">{guide.title}</h3>
38-
<TruncateLines maxLines={8} className="color-fg-muted f5 my-4">
39-
<span dangerouslySetInnerHTML={{ __html: guide.intro }} />
40-
</TruncateLines>
41-
</Link>
42-
</li>
43-
))
4+
export function GuidesHero() {
5+
const { title, intro } = useProductGuidesContext()
446

457
return (
468
<div>
47-
<header className="d-flex gutter mb-6 my-4">
9+
<header className="gutter mb-6 my-4">
4810
<div className="col-12">
4911
<h1 id="title-h1">{title}</h1>
5012
{intro && <Lead data-search="lead">{intro}</Lead>}
5113
</div>
5214
</header>
53-
{featuredTrack && featuredTrack.guides && featuredTrack.guides.length > 0 && (
54-
<div className="mb-6 position-relative overflow-hidden mr-n3 ml-n3 px-3">
55-
<ul
56-
data-testid="feature-track"
57-
className="list-style-none d-flex flex-nowrap overflow-x-scroll px-2"
58-
>
59-
<li className="px-2 d-flex flex-shrink-0" style={{ width: firstCardWidth }}>
60-
<div className="d-inline-block Box p-5 color-bg-subtle">
61-
<div
62-
className="d-inline-flex flex-items-center flex-justify-center circle border"
63-
style={{ width: 40, height: 40, border: '2px white solid' }}
64-
>
65-
<StarFillIcon size={24} />
66-
</div>
67-
<h2 className="text-semibold my-4 f3">{featuredTrack.title}</h2>
68-
<div className="f5 my-4">{featuredTrack.description}</div>
69-
<Link
70-
{...{ 'aria-label': `${featuredTrack.title} - ${t('start_path')}` }}
71-
className="d-inline-flex flex-items-center flex-justify-center btn ws-normal px-4 py-2 f5 no-underline text-bold"
72-
role="button"
73-
href={`${featuredTrack.guides[0].href}?learn=${featuredTrack.trackName}&learnProduct=${featuredTrack.trackProduct}`}
74-
>
75-
{t(`start_path`)}
76-
<ArrowRightIcon size={20} className="ml-2" />
77-
</Link>
78-
</div>
79-
</li>
80-
{guideItems}
81-
</ul>
82-
<div
83-
className={cx('position-absolute top-0 bottom-0 left-0 ml-3 pl-3', styles.fadeLeft)}
84-
></div>
85-
<div
86-
className={cx('position-absolute top-0 bottom-0 right-0 mr-3 pr-3', styles.fadeRight)}
87-
></div>
88-
</div>
89-
)}
9015
</div>
9116
)
9217
}

src/landings/components/ProductGuidesContext.tsx

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createContext, useContext } from 'react'
22
import pick from 'lodash/pick'
33

4-
export type FeaturedTrack = {
4+
export type LearningTrack = {
55
trackName: string
66
trackProduct: string
77
title: string
@@ -20,8 +20,7 @@ export type ArticleGuide = {
2020
export type ProductGuidesContextT = {
2121
title: string
2222
intro: string
23-
featuredTrack?: FeaturedTrack
24-
learningTracks?: Array<FeaturedTrack>
23+
learningTracks?: Array<LearningTrack>
2524
includeGuides?: Array<ArticleGuide>
2625
allTopics?: Array<string>
2726
}
@@ -45,14 +44,6 @@ export const getProductGuidesContextFromRequest = (req: any): ProductGuidesConte
4544

4645
return {
4746
...pick(page, ['title', 'intro', 'allTopics']),
48-
featuredTrack: page.featuredTrack
49-
? {
50-
...pick(page.featuredTrack, ['title', 'description', 'trackName', 'trackProduct']),
51-
guides: (page.featuredTrack?.guides || []).map((guide: any) => {
52-
return pick(guide, ['title', 'intro', 'href', 'page.type'])
53-
}),
54-
}
55-
: null,
5647
learningTracks: (page.learningTracks || []).map((track: any) => ({
5748
...pick(track, ['title', 'description', 'trackName', 'trackProduct']),
5849
guides: (track.guides || []).map((guide: any) => {

src/learning-track/components/guides/LearningTrack.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { useTranslation } from 'components/hooks/useTranslation'
33
import { ArrowRightIcon } from '@primer/octicons-react'
44
import { ActionList } from '@primer/react'
55
import { useState } from 'react'
6-
import { FeaturedTrack } from 'src/landings/components/ProductGuidesContext'
6+
import { LearningTrack as LearningTrackT } from 'src/landings/components/ProductGuidesContext'
77
import { TruncateLines } from 'components/ui/TruncateLines'
88
import { slug } from 'github-slugger'
99
import styles from './LearningTrack.module.scss'
1010
import { Link } from 'components/Link'
1111

1212
type Props = {
13-
track: FeaturedTrack
13+
track: LearningTrackT
1414
}
1515

1616
const DEFAULT_VISIBLE_GUIDES = 4

src/learning-track/lib/process-learning-tracks.js

+3-21
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,11 @@ const renderOpts = { textOnly: true }
1111
export default async function processLearningTracks(rawLearningTracks, context) {
1212
const learningTracks = []
1313

14-
let featuredTrack
15-
1614
if (!context.currentProduct) {
1715
throw new Error(`Missing context.currentProduct value.`)
1816
}
1917

2018
for (const rawTrackName of rawLearningTracks) {
21-
let isFeaturedTrack = false
22-
2319
// Track names in frontmatter may include Liquid conditionals.
2420
const renderedTrackName = await renderContent(rawTrackName, context, renderOpts)
2521
if (!renderedTrackName) continue
@@ -48,7 +44,7 @@ export default async function processLearningTracks(rawLearningTracks, context)
4844
// We do this for two reasons:
4945
//
5046
// 1. For each learning-track .yml file (in data) always want the
51-
// English values for `guides`, `versions`, `featured_track`.
47+
// English values for `guides`, `versions`.
5248
// Meaning, for the translated learning tracks we only keep the
5349
// `title` and `description`.
5450
//
@@ -69,7 +65,6 @@ export default async function processLearningTracks(rawLearningTracks, context)
6965
// from the English equivalent.
7066
track.guides = enTrack.guides
7167
track.versions = enTrack.versions
72-
track.featured_track = enTrack.featured_track
7368
}
7469

7570
// If there is no `versions` prop in the learning track frontmatter, assume the track should display in all versions.
@@ -103,24 +98,11 @@ export default async function processLearningTracks(rawLearningTracks, context)
10398
guides: await getLinkData(track.guides, context),
10499
}
105100

106-
// Determine if this is the featured track.
107-
if (track.featured_track) {
108-
// Featured track properties may be booleans or string that include Liquid conditionals with versioning.
109-
// We need to parse any strings to determine if the featured track is relevant for this version.
110-
isFeaturedTrack =
111-
track.featured_track === true ||
112-
(await renderContent(track.featured_track, context, renderOpts)) === 'true'
113-
114-
if (isFeaturedTrack) {
115-
featuredTrack = learningTrack
116-
}
117-
}
118-
119101
// Only add the track to the array of tracks if there are guides in this version and it's not the featured track.
120-
if (learningTrack.guides.length && !isFeaturedTrack) {
102+
if (learningTrack.guides.length) {
121103
learningTracks.push(learningTrack)
122104
}
123105
}
124106

125-
return { featuredTrack, learningTracks }
107+
return { learningTracks }
126108
}

0 commit comments

Comments
 (0)