Skip to content

Commit b3ca4b7

Browse files
authored
Merge pull request #46231 from github/repo-sync
Repo sync
2 parents 73050b4 + 2c5e31e commit b3ca4b7

15 files changed

Lines changed: 174 additions & 42 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Add persona-labeled issues and PRs to Docs Content Review Board
2+
3+
# When the builder persona or driver persona label is added to an issue or PR
4+
# in github/docs, add it to the Docs Content Review Board project.
5+
6+
on:
7+
issues:
8+
types: [labeled]
9+
pull_request_target:
10+
types: [labeled]
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
add-to-review-board:
17+
name: Add to Docs Content Review Board
18+
runs-on: ubuntu-latest
19+
if: >-
20+
github.repository == 'github/docs' &&
21+
(github.event.label.name == 'builder persona' || github.event.label.name == 'driver persona')
22+
steps:
23+
- name: Add item to project
24+
env:
25+
GITHUB_TOKEN: ${{ secrets.DOCS_BOT_PAT_BASE }}
26+
ITEM_URL: ${{ github.event.issue.html_url || github.event.pull_request.html_url }}
27+
PROJECT_NUMBER: 2936
28+
run: |
29+
echo "Adding $ITEM_URL to project $PROJECT_NUMBER..."
30+
gh project item-add "$PROJECT_NUMBER" --owner github --url "$ITEM_URL"

‎.github/workflows/moda-ci.yaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ permissions: {}
1515

1616
jobs:
1717
set-vault-keys:
18+
# Merge queue already built and checked this SHA. Repo-sync and admin merges bypass the queue and still build.
19+
# The actor check only skips a duplicate build and grants no access.
20+
if: ${{ !(github.event_name == 'push' && github.ref == 'refs/heads/main' && github.actor == 'github-merge-queue[bot]') }} # zizmor: ignore[bot-conditions]
1821
permissions: {}
1922
runs-on: ubuntu-latest
2023
outputs:

‎package-lock.json‎

Lines changed: 18 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
"ajv": "^8.18.0",
192192
"ajv-errors": "^3.0.0",
193193
"ajv-formats": "^3.0.1",
194-
"chalk": "^5.0.1",
194+
"chalk": "^6.0.1",
195195
"cheerio": "^1.2.0",
196196
"clsx": "^2.1.1",
197197
"cookie-parser": "^1.4.7",

‎src/color-schemes/README.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,27 @@ The resolved mode comes from the **effective theme**, not the raw `color_mode`,
5353

5454
This is a workaround for a gap in Brand and belongs upstream; until it lands, every consumer has to hand Brand a concrete mode.
5555

56+
### Color contrast requirements
57+
58+
Colors must meet WCAG 2.1 AA in every supported mode. Primer documents the requirements in [ADR-010: Color contrast requirements](https://github.com/primer/primitives/blob/main/contributor-docs/adrs/adr-010-color-contrast.md). The ones that come up most often are:
59+
60+
| Pair | Minimum ratio |
61+
|---|---|
62+
| Text vs. any background it can sit on | 4.5:1 |
63+
| Large text, icons, and other non-text UI vs. background | 3:1 |
64+
| Link vs. surrounding text | 3:1, unless the link is underlined. Links also need 4.5:1 against the background. |
65+
| Focus indicator vs. adjacent colors | 3:1 |
66+
| Border of a control that contains text, or a decorative border | None |
67+
68+
Check both light and dark mode. Brand's base color scales (`--base-color-scale-*`) don't invert in dark mode, so a step that passes in light mode can fail in dark mode.
69+
70+
Also check the no-JavaScript fallback, where `<html>` keeps `data-color-mode="auto"`. Brand stays on its light palette there, so a component that darkens its own background still gets light-mode link blue. Scope fallback selectors to `html`, because the `@primer/react` `ThemeProvider` wrapper also starts as `auto`.
71+
72+
On colored surfaces, such as the `Banner` component in `src/frame/components/ui/Banner/`, we enforce these rules:
73+
74+
* Always underline links. Don't rely on link color to separate links from surrounding text.
75+
* If the link color can't be guaranteed to reach 4.5:1 against the surface, set links to the surface's text color.
76+
5677
## Setup & Usage
5778

5879
To access the current theme in a component:
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Colors follow the Docs 2026 Figma warning banner: Brand yellow-9 text with a yellow-7 accent.
2+
// Default and danger reuse the same scale steps in blue and red.
3+
// Brand's base scales do not invert in dark mode, so dark mode mirrors the steps explicitly,
4+
// the same way Brand's own component tokens pair a light step with a dark step.
5+
@mixin banner-colors($hue, $mode) {
6+
@if $mode == light {
7+
--banner-bg: var(--base-color-scale-#{$hue}-0);
8+
--banner-border: var(--base-color-scale-#{$hue}-7);
9+
--banner-fg: var(--base-color-scale-#{$hue}-9);
10+
} @else {
11+
--banner-bg: var(--base-color-scale-#{$hue}-9);
12+
--banner-border: var(--base-color-scale-#{$hue}-2);
13+
--banner-fg: var(--base-color-scale-#{$hue}-0);
14+
}
15+
}
16+
17+
@mixin banner-variant($hue) {
18+
@include banner-colors($hue, light);
19+
20+
:global([data-color-mode="dark"]) & {
21+
@include banner-colors($hue, dark);
22+
}
23+
24+
// No-JS fallback; see the note in src/frame/stylesheets/index.scss. Scoped to html because
25+
// the @primer/react ThemeProvider wrapper also starts as auto, even when html is light.
26+
// Brand keeps its light link blue here, so links use the banner text color for contrast.
27+
@media (prefers-color-scheme: dark) {
28+
:global(html[data-color-mode="auto"][data-dark-theme*="dark"]) & {
29+
@include banner-colors($hue, dark);
30+
31+
a {
32+
color: var(--banner-fg);
33+
}
34+
}
35+
}
36+
}
37+
38+
.banner {
39+
padding: var(--base-size-16, 1rem);
40+
color: var(--banner-fg);
41+
background-color: var(--banner-bg);
42+
border: var(--brand-borderWidth-thin, 1px) solid var(--banner-border);
43+
border-radius: var(--brand-borderRadius-medium, 0.5rem);
44+
45+
p:last-child {
46+
margin-bottom: 0;
47+
}
48+
49+
// Link color alone is not distinct enough from banner text, especially in dark mode.
50+
a {
51+
text-decoration: underline;
52+
}
53+
}
54+
55+
.default {
56+
@include banner-variant(blue);
57+
}
58+
59+
.warning {
60+
@include banner-variant(yellow);
61+
}
62+
63+
.danger {
64+
@include banner-variant(red);
65+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { ReactNode } from 'react'
2+
import cx from 'clsx'
3+
4+
import styles from './Banner.module.scss'
5+
6+
export type BannerPropsT = {
7+
variant?: 'default' | 'warning' | 'danger'
8+
className?: string
9+
children: ReactNode
10+
}
11+
12+
// No live region role: every banner renders with the page and never updates in place.
13+
export function Banner({ variant = 'default', className, children }: BannerPropsT) {
14+
return <div className={cx(styles.banner, styles[variant], className)}>{children}</div>
15+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { Banner } from './Banner'
2+
export type { BannerPropsT } from './Banner'

‎src/rest/components/RestBanner.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from 'react'
2-
import { Flash } from '@primer/react'
32
import { useRouter } from 'next/router'
43

54
import { DEFAULT_VERSION, useVersion } from '@/versions/components/useVersion'
65
import { Link } from '@/frame/components/Link'
6+
import { Banner } from '@/frame/components/ui/Banner'
77
import { useMainContext } from '@/frame/components/context/MainContext'
88
import { useTranslation } from '@/languages/components/useTranslation'
99
import { RenderedHTML } from '@/frame/components/ui/RenderedHTML/RenderedHTML'
@@ -76,7 +76,7 @@ export const RestBanner = () => {
7676
data-testid="rest-api-versioning-temporary-banner"
7777
className="container-xl mt-3 mx-auto p-responsive"
7878
>
79-
<Flash>
79+
<Banner>
8080
<RenderedHTML as="span" html={bannerText} />{' '}
8181
<RenderedHTML
8282
as="span"
@@ -85,7 +85,7 @@ export const RestBanner = () => {
8585
versionWithApiVersion === DEFAULT_VERSION ? '' : `/${versionWithApiVersion}`,
8686
)}
8787
/>
88-
</Flash>
88+
</Banner>
8989
</div>
9090
)
9191
}
@@ -130,15 +130,15 @@ export const RestBanner = () => {
130130

131131
return (
132132
<div data-testid="rest-api-repos-banner" className="container-xl mt-3 mx-auto p-responsive">
133-
<Flash variant="warning">
133+
<Banner variant="warning">
134134
<p>
135135
<b className="text-bold">
136136
<span>
137137
{t('rest.banner.redirect_notice')} {noticeString}
138138
</span>
139139
</b>{' '}
140140
</p>
141-
</Flash>
141+
</Banner>
142142
</div>
143143
)
144144
}

‎src/search/components/results/NoQuery.module.scss‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
line-height: 1.2;
66
}
77

8-
.flash {
8+
.banner {
99
margin: 2rem;
1010
}

0 commit comments

Comments
 (0)