Replace sx and inline style declarations with CSS modules (#57848)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
16
src/audit-logs/components/GroupedEvents.module.scss
Normal file
16
src/audit-logs/components/GroupedEvents.module.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
.eventItem {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.eventAction {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.eventDetail {
|
||||
margin-left: 1rem;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.eventDescription {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import { HeadingLink } from '@/frame/components/article/HeadingLink'
|
||||
import { useTranslation } from '@/languages/components/useTranslation'
|
||||
import type { AuditLogEventT } from '../types'
|
||||
|
||||
import styles from './GroupedEvents.module.scss'
|
||||
|
||||
type Props = {
|
||||
auditLogEvents: AuditLogEventT[]
|
||||
category: string
|
||||
@@ -47,15 +49,15 @@ export default function GroupedEvents({ auditLogEvents, category, categoryNote }
|
||||
)}
|
||||
<div>
|
||||
{auditLogEvents.map((event) => (
|
||||
<div key={event.action} style={{ marginBottom: '3rem' }}>
|
||||
<div key={event.action} className={styles.eventItem}>
|
||||
<dl>
|
||||
<dt style={{ fontStyle: 'normal' }}>
|
||||
<dt className={styles.eventAction}>
|
||||
<code>{event.action}</code>
|
||||
</dt>
|
||||
<dd>{event.description}</dd>
|
||||
|
||||
<dt style={{ marginLeft: '1rem', fontStyle: 'normal' }}>{t('fields')}</dt>
|
||||
<dd style={{ marginLeft: '1rem' }}>
|
||||
<dt className={styles.eventDetail}>{t('fields')}</dt>
|
||||
<dd className={styles.eventDescription}>
|
||||
{event.fields
|
||||
? event.fields.map((field, index) => (
|
||||
<span key={field}>
|
||||
@@ -68,8 +70,8 @@ export default function GroupedEvents({ auditLogEvents, category, categoryNote }
|
||||
|
||||
{event.docs_reference_links && event.docs_reference_links !== 'N/A' && (
|
||||
<>
|
||||
<dt style={{ marginLeft: '1rem', fontStyle: 'normal' }}>{t('reference')}</dt>
|
||||
<dd style={{ marginLeft: '1rem' }}>{renderReferenceLinks(event)}</dd>
|
||||
<dt className={styles.eventDetail}>{t('reference')}</dt>
|
||||
<dd className={styles.eventDescription}>{renderReferenceLinks(event)}</dd>
|
||||
</>
|
||||
)}
|
||||
</dl>
|
||||
|
||||
3
src/frame/components/DefaultLayout.module.scss
Normal file
3
src/frame/components/DefaultLayout.module.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.mainContent {
|
||||
scroll-margin-top: 5rem;
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import { useLanguages } from '@/languages/components/LanguagesContext'
|
||||
import { ClientSideLanguageRedirect } from './ClientSideLanguageRedirect'
|
||||
import { SearchOverlayContextProvider } from '@/search/components/context/SearchOverlayContext'
|
||||
|
||||
import styles from './DefaultLayout.module.scss'
|
||||
|
||||
const MINIMAL_RENDER = Boolean(JSON.parse(process.env.MINIMAL_RENDER || 'false'))
|
||||
|
||||
type Props = { children?: React.ReactNode }
|
||||
@@ -51,7 +53,7 @@ export const DefaultLayout = (props: Props) => {
|
||||
<Breadcrumbs />
|
||||
</div>
|
||||
|
||||
<main id="main-content" style={{ scrollMarginTop: '5rem' }}>
|
||||
<main id="main-content" className={styles.mainContent}>
|
||||
{props.children}
|
||||
</main>
|
||||
</div>
|
||||
@@ -150,7 +152,7 @@ export const DefaultLayout = (props: Props) => {
|
||||
{/* Need to set an explicit height for sticky elements since we also
|
||||
set overflow to auto */}
|
||||
<div className="flex-column flex-1 min-width-0">
|
||||
<main id="main-content" style={{ scrollMarginTop: '5rem' }}>
|
||||
<main id="main-content" className={styles.mainContent}>
|
||||
<DeprecationBanner />
|
||||
<RestBanner />
|
||||
|
||||
|
||||
3
src/frame/components/GenericError.module.scss
Normal file
3
src/frame/components/GenericError.module.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.logoContainer {
|
||||
z-index: 3;
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import { useRouter } from 'next/router'
|
||||
import { MarkGithubIcon, CommentDiscussionIcon } from '@primer/octicons-react'
|
||||
import { Lead } from '@/frame/components/ui/Lead'
|
||||
|
||||
import styles from './GenericError.module.scss'
|
||||
|
||||
export function GenericError() {
|
||||
return (
|
||||
<div className="min-h-screen d-flex flex-column">
|
||||
@@ -44,7 +46,7 @@ export const SimpleHeader = () => {
|
||||
role="banner"
|
||||
aria-label="Main"
|
||||
>
|
||||
<div className="d-flex flex-items-center" style={{ zIndex: 3 }} id="github-logo-mobile">
|
||||
<div className={`d-flex flex-items-center ${styles.logoContainer}`} id="github-logo-mobile">
|
||||
<Link href={`/${router.locale}`} aria-hidden="true" tabIndex={-1}>
|
||||
<MarkGithubIcon size={32} className="color-fg-default" />
|
||||
</Link>
|
||||
|
||||
@@ -57,3 +57,7 @@
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.headerContainer {
|
||||
row-gap: 1rem;
|
||||
}
|
||||
|
||||
@@ -156,11 +156,10 @@ export const Header = () => {
|
||||
aria-label="Main"
|
||||
>
|
||||
<div
|
||||
className="d-flex flex-justify-between p-2 flex-items-center flex-wrap"
|
||||
style={{
|
||||
// In the rare case of header overflow, create a pleasant gap between the rows
|
||||
rowGap: '1rem',
|
||||
}}
|
||||
className={cx(
|
||||
'd-flex flex-justify-between p-2 flex-items-center flex-wrap',
|
||||
styles.headerContainer,
|
||||
)}
|
||||
data-testid="desktop-header"
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -10,3 +10,29 @@
|
||||
visibility: hidden !important;
|
||||
}
|
||||
}
|
||||
|
||||
// The ... menu button when the smaller width search UI is open. Since the search
|
||||
// UI is open, we don't show the button at smaller widths but we do show it as
|
||||
// the browser width increases to md, and then at lg and above widths we hide
|
||||
// the button again since the pickers and sign-up button are shown in the header.
|
||||
.menuButtonSearchOpen {
|
||||
margin-left: 0.5rem;
|
||||
display: none;
|
||||
|
||||
@include breakpoint(md) {
|
||||
display: inline-block;
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
// The ... menu button when the smaller width search UI is closed, the button is
|
||||
// shown up to lg. At lg and above we don't show the button since the pickers
|
||||
// and sign-up button are shown in the header.
|
||||
.menuButtonSearchClosed {
|
||||
margin-left: 1rem;
|
||||
|
||||
@include breakpoint(lg) {
|
||||
margin-left: 0;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,36 +55,8 @@ export function HeaderSearchAndWidgets({ width, isSearchOpen, SearchButton }: Pr
|
||||
data-testid="mobile-menu"
|
||||
icon={KebabHorizontalIcon}
|
||||
aria-label={t('header.open_menu_label')}
|
||||
sx={
|
||||
isSearchOpen
|
||||
? // The ... menu button when the smaller width search UI is open. Since the search
|
||||
// UI is open, we don't show the button at smaller widths but we do show it as
|
||||
// the browser width increases to md, and then at lg and above widths we hide
|
||||
// the button again since the pickers and sign-up button are shown in the header.
|
||||
{
|
||||
marginLeft: '8px',
|
||||
display: 'none',
|
||||
// breakpoint(md)
|
||||
'@media (min-width: 768px)': {
|
||||
display: 'inline-block',
|
||||
marginLeft: '4px',
|
||||
},
|
||||
// breakpoint(lg)
|
||||
'@media (min-width: 1012px)': {
|
||||
display: 'inline-block',
|
||||
marginLeft: '4px',
|
||||
},
|
||||
}
|
||||
: // The ... menu button when the smaller width search UI is closed, the button is
|
||||
// shown up to md. At lg and above we don't show the button since the pickers
|
||||
// and sign-up button are shown in the header.
|
||||
{
|
||||
marginLeft: '16px',
|
||||
'@media (min-width: 1012px)': {
|
||||
marginLeft: '0',
|
||||
display: 'none',
|
||||
},
|
||||
}
|
||||
className={
|
||||
isSearchOpen ? styles.menuButtonSearchOpen : styles.menuButtonSearchClosed
|
||||
}
|
||||
/>
|
||||
</ActionMenu.Anchor>
|
||||
|
||||
33
src/frame/components/sidebar/SidebarNav.module.scss
Normal file
33
src/frame/components/sidebar/SidebarNav.module.scss
Normal file
@@ -0,0 +1,33 @@
|
||||
.sidebarFull {
|
||||
// Fixed width for consistent sidebar layout
|
||||
width: 326px;
|
||||
// 65px accounts for the header height
|
||||
height: calc(100vh - 65px);
|
||||
top: 65px;
|
||||
}
|
||||
|
||||
.sidebarContentFull {
|
||||
width: 326px;
|
||||
// 175px accounts for header (65px) + sidebar header (110px)
|
||||
height: calc(100vh - 175px);
|
||||
}
|
||||
|
||||
.sidebarContentOverlay {
|
||||
// Padding to account for header + sidebar header so content isn't cut off
|
||||
padding-bottom: 185px;
|
||||
}
|
||||
|
||||
.sidebarContentOverlayRest {
|
||||
// Extra padding for REST pages (includes API version picker)
|
||||
padding-bottom: 250px;
|
||||
}
|
||||
|
||||
.sidebarContentFullWithPadding {
|
||||
// Padding to account for header + sidebar header so content isn't cut off
|
||||
padding-bottom: 185px;
|
||||
}
|
||||
|
||||
.sidebarContentFullWithPaddingRest {
|
||||
// Extra padding for REST pages (includes API version picker)
|
||||
padding-bottom: 250px;
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import { AllProductsLink } from './AllProductsLink'
|
||||
import { ApiVersionPicker } from '@/rest/components/ApiVersionPicker'
|
||||
import { Link } from '@/frame/components/Link'
|
||||
|
||||
import styles from './SidebarNav.module.scss'
|
||||
|
||||
type Props = {
|
||||
variant?: 'full' | 'overlay'
|
||||
}
|
||||
@@ -22,20 +24,15 @@ export const SidebarNav = ({ variant = 'full' }: Props) => {
|
||||
// Early access does not have a "home page" unless it's local dev
|
||||
(process.env.NODE_ENV === 'development' || currentProduct.id !== 'early-access')
|
||||
|
||||
// we need to roughly account for the site header height plus the height of
|
||||
// the side nav header (which is taller when we show the API version picker)
|
||||
// so we don't cut off the bottom of the sidebar
|
||||
const sidebarPaddingBottom = isRestPage ? '250px' : '185px'
|
||||
|
||||
const isSearch = currentProduct?.id === 'search'
|
||||
|
||||
return (
|
||||
<div
|
||||
data-container="nav"
|
||||
className={cx(variant === 'full' ? 'position-sticky d-none border-right d-xxl-block' : '')}
|
||||
style={
|
||||
variant === 'full' ? { width: 326, height: 'calc(100vh - 65px)', top: '65px' } : undefined
|
||||
}
|
||||
className={cx(
|
||||
variant === 'full' ? 'position-sticky d-none border-right d-xxl-block' : '',
|
||||
variant === 'full' && styles.sidebarFull,
|
||||
)}
|
||||
>
|
||||
<nav
|
||||
aria-labelledby="allproducts-menu"
|
||||
@@ -68,12 +65,16 @@ export const SidebarNav = ({ variant = 'full' }: Props) => {
|
||||
? 'width-full d-xxl-none'
|
||||
: 'border-right d-none d-xxl-block overflow-y-auto',
|
||||
'bg-primary flex-shrink-0',
|
||||
)}
|
||||
style={
|
||||
variant === 'overlay'
|
||||
? { paddingBottom: sidebarPaddingBottom }
|
||||
: { width: 326, height: 'calc(100vh - 175px)', paddingBottom: sidebarPaddingBottom }
|
||||
}
|
||||
? isRestPage
|
||||
? styles.sidebarContentOverlayRest
|
||||
: styles.sidebarContentOverlay
|
||||
: styles.sidebarContentFull,
|
||||
variant === 'full' &&
|
||||
(isRestPage
|
||||
? styles.sidebarContentFullWithPaddingRest
|
||||
: styles.sidebarContentFullWithPadding),
|
||||
)}
|
||||
role="region"
|
||||
aria-label="Page navigation content"
|
||||
>
|
||||
|
||||
@@ -32,3 +32,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.codeBlockContainer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.copyButton {
|
||||
position: absolute;
|
||||
right: -0.7rem;
|
||||
top: -0.7rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import useCopyClipboard from '@/rest/components/useClipboard'
|
||||
import { EventType } from '@/events/types'
|
||||
import { sendEvent } from '@/events/components/events'
|
||||
|
||||
import styles from './MarkdownContent.module.scss'
|
||||
|
||||
export type MarkdownContentPropsT = {
|
||||
children: string
|
||||
className?: string
|
||||
@@ -72,11 +74,11 @@ export const UnrenderedMarkdownContent = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div className={styles.codeBlockContainer}>
|
||||
<IconButton
|
||||
size="small"
|
||||
icon={isCopied ? CheckIcon : CopyIcon}
|
||||
className="btn-octicon"
|
||||
className={cx('btn-octicon', styles.copyButton)}
|
||||
aria-label={getAriaLabel()}
|
||||
onClick={async () => {
|
||||
await copyToClipboard()
|
||||
@@ -88,12 +90,6 @@ export const UnrenderedMarkdownContent = ({
|
||||
eventGroupId: eventGroupId,
|
||||
})
|
||||
}}
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
right: '-.7rem',
|
||||
top: '-.7rem',
|
||||
zIndex: 1,
|
||||
}}
|
||||
></IconButton>
|
||||
<code {...props}>{props.children}</code>
|
||||
</div>
|
||||
|
||||
@@ -59,13 +59,7 @@ export function MiniTocs({ miniTocItems }: MiniTocsPropsT) {
|
||||
<Heading
|
||||
as="h2"
|
||||
id="in-this-article"
|
||||
className="mb-1 ml-3"
|
||||
sx={{
|
||||
'@media (min-width: 1012px) and (max-width: 1400px)': {
|
||||
marginTop: '2rem',
|
||||
},
|
||||
fontSize: 1,
|
||||
}}
|
||||
className={cx('mb-1 ml-3', styles.heading)}
|
||||
aria-label={t('miniToc')}
|
||||
>
|
||||
{t('miniToc')}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
@import "@primer/css/support/variables/layout.scss";
|
||||
@import "@primer/css/support/mixins/layout.scss";
|
||||
@import "src/frame/stylesheets/breakpoint-xxl.scss";
|
||||
|
||||
.indentNested {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
@@ -18,3 +22,15 @@
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-size: var(--text-body-size-small);
|
||||
|
||||
@include breakpoint(lg) {
|
||||
margin-top: 2rem;
|
||||
|
||||
@include breakpoint-xxl {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.permissionsBox {
|
||||
border-radius: 0.625rem;
|
||||
border-style: solid;
|
||||
border-color: var(--borderColor-default);
|
||||
padding: var(--base-size-16);
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Box } from '@primer/react'
|
||||
import { PersonIcon, BriefcaseIcon } from '@primer/octicons-react'
|
||||
|
||||
import { useTranslation } from '@/languages/components/useTranslation'
|
||||
|
||||
import styles from './PermissionsStatement.module.scss'
|
||||
|
||||
type Props = {
|
||||
product?: string
|
||||
permissions?: string
|
||||
@@ -12,7 +13,7 @@ export function PermissionsStatement({ product, permissions }: Props) {
|
||||
const { t } = useTranslation('pages')
|
||||
if (!permissions && !product) return null
|
||||
return (
|
||||
<Box sx={{ borderRadius: 10, borderStyle: 'solid', borderColor: 'border.default', p: 3 }}>
|
||||
<div className={styles.permissionsBox}>
|
||||
<div data-search="hide" data-testid="permissions-callout">
|
||||
<div className="mb-3 d-inline-block">
|
||||
<h2 className="f4">{t('permissions_callout_title')}</h2>
|
||||
@@ -30,6 +31,6 @@ export function PermissionsStatement({ product, permissions }: Props) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,3 +16,8 @@
|
||||
outline-offset: -2px;
|
||||
box-shadow: 0 0 0 4px inset; // A little wider for the border radius :shrug:
|
||||
}
|
||||
|
||||
.scrollButton {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import cx from 'classnames'
|
||||
import { ChevronUpIcon } from '@primer/octicons-react'
|
||||
|
||||
import styles from './ScrollButton.module.scss'
|
||||
|
||||
const { transition200, opacity0, opacity100, customFocus } = styles
|
||||
@@ -70,8 +71,8 @@ export const ScrollButton = ({ className, ariaLabel }: ScrollButtonPropsT) => {
|
||||
'tooltipped tooltipped-n tooltipped-no-delay btn circle border-1',
|
||||
'd-flex flex-items-center flex-justify-center',
|
||||
customFocus,
|
||||
styles.scrollButton,
|
||||
)}
|
||||
style={{ width: 40, height: 40 }}
|
||||
aria-label={ariaLabel}
|
||||
>
|
||||
<ChevronUpIcon />
|
||||
|
||||
3
src/graphql/pages/explorer.module.scss
Normal file
3
src/graphql/pages/explorer.module.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.explorerIframe {
|
||||
height: 45rem;
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
} from '@/automated-pipelines/components/AutomatedPageContext'
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
import styles from './explorer.module.scss'
|
||||
|
||||
type Props = {
|
||||
mainContext: MainContextT
|
||||
graphqlExplorerUrl: string
|
||||
@@ -34,8 +36,7 @@ export default function GQLExplorer({
|
||||
<div>
|
||||
<iframe
|
||||
ref={graphiqlRef}
|
||||
style={{ height: 715 }}
|
||||
className="border width-full"
|
||||
className={`border width-full ${styles.explorerIframe}`}
|
||||
scrolling="no"
|
||||
src={graphqlExplorerUrl}
|
||||
title="GitHub GraphQL API"
|
||||
|
||||
12
src/languages/components/LanguagePicker.module.scss
Normal file
12
src/languages/components/LanguagePicker.module.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
.menuButton {
|
||||
height: auto;
|
||||
text-align: left;
|
||||
|
||||
span:first-child {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.languageLabel {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import { useTranslation } from '@/languages/components/useTranslation'
|
||||
import { useUserLanguage } from '@/languages/components/useUserLanguage'
|
||||
import { ActionList, ActionMenu, IconButton } from '@primer/react'
|
||||
|
||||
import styles from './LanguagePicker.module.scss'
|
||||
|
||||
type Props = {
|
||||
xs?: boolean
|
||||
mediumOrLower?: boolean
|
||||
@@ -79,15 +81,10 @@ export const LanguagePicker = ({ xs, mediumOrLower }: Props) => {
|
||||
<ActionMenu.Anchor>
|
||||
<ActionMenu.Button
|
||||
variant="invisible"
|
||||
className="color-fg-default width-full"
|
||||
className={`color-fg-default width-full ${styles.menuButton}`}
|
||||
aria-label={`Select language: current language is ${selectedLang.name}`}
|
||||
sx={{
|
||||
height: 'auto',
|
||||
textAlign: 'left',
|
||||
'span:first-child': { display: 'inline' },
|
||||
}}
|
||||
>
|
||||
<span style={{ whiteSpace: 'pre-wrap' }}>{t('language_picker_label') + '\n'}</span>
|
||||
<span className={styles.languageLabel}>{t('language_picker_label') + '\n'}</span>
|
||||
<span className="color-fg-muted text-normal f6">{selectedLang.name}</span>
|
||||
</ActionMenu.Button>
|
||||
</ActionMenu.Anchor>
|
||||
|
||||
@@ -6,6 +6,8 @@ import { PatchNotes } from './PatchNotes'
|
||||
import { Link } from '@/frame/components/Link'
|
||||
import { CurrentVersion, ReleaseNotePatch, GHESMessage } from './types'
|
||||
|
||||
import styles from './PatchNotes.module.scss'
|
||||
|
||||
type Props = {
|
||||
patch: ReleaseNotePatch
|
||||
currentVersion: CurrentVersion
|
||||
@@ -26,8 +28,7 @@ export function GHESReleaseNotePatch({
|
||||
return (
|
||||
<div ref={containerRef} className="mb-10 pb-6" id={patch.version}>
|
||||
<header
|
||||
style={{ zIndex: 1, marginTop: -1 }}
|
||||
className="container-md border-top border-bottom px-3 pt-4 pb-2"
|
||||
className={`container-md border-top border-bottom px-3 pt-4 pb-2 ${styles.patchHeader}`}
|
||||
>
|
||||
<div className="d-flex flex-justify-between flex-wrap">
|
||||
<h2 className="border-bottom-0 m-0 p-0 mt-2">
|
||||
@@ -36,8 +37,7 @@ export function GHESReleaseNotePatch({
|
||||
|
||||
{patch.release_candidate && (
|
||||
<span
|
||||
className="IssueLabel color-bg-attention-emphasis color-fg-on-emphasis ml-3 flex-items-center d-inline-flex"
|
||||
style={{ whiteSpace: 'pre' }}
|
||||
className={`IssueLabel color-bg-attention-emphasis color-fg-on-emphasis ml-3 flex-items-center d-inline-flex ${styles.releaseLabel}`}
|
||||
>
|
||||
Release Candidate
|
||||
</span>
|
||||
|
||||
@@ -14,3 +14,12 @@
|
||||
top: 65px;
|
||||
}
|
||||
}
|
||||
|
||||
.patchHeader {
|
||||
z-index: 1;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.releaseLabel {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
.responseCodeBlock {
|
||||
min-height: 120px;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
.segmentedControl {
|
||||
|
||||
@@ -100,7 +100,6 @@ export function RestCodeSamples({ operation, slug, heading }: Props) {
|
||||
const [selectedLanguage, setSelectedLanguage] = useState(languageSelectOptions[0])
|
||||
const [selectedExample, setSelectedExample] = useState(exampleSelectOptions[0])
|
||||
const [selectedResponse, setSelectedResponse] = useState(responseSelectOptions[0])
|
||||
const [responseMaxHeight, setResponseMaxHeight] = useState(0)
|
||||
|
||||
const isSingleExample = languageExamples.length === 1
|
||||
const displayedExample: ExampleT = languageExamples[selectedExample.languageIndex]
|
||||
@@ -118,19 +117,6 @@ export function RestCodeSamples({ operation, slug, heading }: Props) {
|
||||
Cookies.set('codeSampleLanguagePreferred', languageKey)
|
||||
}
|
||||
|
||||
const handleResponseResize = () => {
|
||||
if (requestCodeExample.current) {
|
||||
const requestCodeHeight = requestCodeExample.current.clientHeight || 0
|
||||
const { innerHeight: height } = window
|
||||
if (responseCodeExample) {
|
||||
// 520 pixels roughly accounts for the space taken up by the
|
||||
// nav bar, headers, language picker, method section, and response
|
||||
// picker
|
||||
setResponseMaxHeight(height - requestCodeHeight - 520)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change the language based on cookies
|
||||
useEffect(() => {
|
||||
// If the user previously selected a language preference and the language
|
||||
@@ -152,7 +138,6 @@ export function RestCodeSamples({ operation, slug, heading }: Props) {
|
||||
// (ClientSideHighlightJS) will have already handled highlighting
|
||||
if (reqElem && !firstRender.current) {
|
||||
highlightElement(reqElem)
|
||||
handleResponseResize()
|
||||
}
|
||||
}, [selectedLanguage])
|
||||
|
||||
@@ -196,15 +181,6 @@ export function RestCodeSamples({ operation, slug, heading }: Props) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Handle the resizing of the response section when the window is resized
|
||||
useEffect(() => {
|
||||
handleResponseResize()
|
||||
window.addEventListener('resize', handleResponseResize)
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResponseResize)
|
||||
}
|
||||
})
|
||||
|
||||
const [isCopied, setCopied] = useClipboard(displayedExample[selectedLanguage] as string, {
|
||||
successDuration: 1400,
|
||||
})
|
||||
@@ -360,7 +336,6 @@ export function RestCodeSamples({ operation, slug, heading }: Props) {
|
||||
'border-top rounded-1 my-0',
|
||||
)}
|
||||
data-highlight={'json'}
|
||||
style={{ maxHeight: responseMaxHeight }}
|
||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
||||
tabIndex={0}
|
||||
>
|
||||
|
||||
@@ -5,3 +5,7 @@
|
||||
.codeBlock code:not(td *) {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.stickyCodeColumn {
|
||||
top: 6.5em;
|
||||
}
|
||||
|
||||
@@ -102,8 +102,10 @@ export function RestOperation({ operation }: Props) {
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="col-md-12 col-lg-6 position-sticky flex-self-start"
|
||||
style={{ top: '6.5em' }}
|
||||
className={cx(
|
||||
'col-md-12 col-lg-6 position-sticky flex-self-start',
|
||||
styles.stickyCodeColumn,
|
||||
)}
|
||||
>
|
||||
{hasCodeSamples && (
|
||||
<RestCodeSamples
|
||||
|
||||
@@ -3,3 +3,10 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.linkItem {
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ActionList } from '@primer/react'
|
||||
import { ReactNode } from 'react'
|
||||
import cx from 'classnames'
|
||||
|
||||
import { PickerItem } from './Picker'
|
||||
|
||||
@@ -34,13 +35,10 @@ export const Fields = (fieldProps: {
|
||||
// variant span box in front of it. To date there isn't a possibility to have
|
||||
// an ActionMenu in Primer that allow non-selection variant items with selection
|
||||
// variant items
|
||||
className={(item.extra?.arrow || item.extra?.info) && styles.extrasDisplay}
|
||||
sx={{
|
||||
':hover': {
|
||||
textDecoration: 'none',
|
||||
textAlign: 'left',
|
||||
},
|
||||
}}
|
||||
className={cx(
|
||||
(item.extra?.arrow || item.extra?.info) && styles.extrasDisplay,
|
||||
styles.linkItem,
|
||||
)}
|
||||
role={item.extra?.arrow || item.extra?.info ? 'menuitem' : 'menuitemradio'}
|
||||
>
|
||||
{renderItem ? renderItem(item) : item.text}
|
||||
|
||||
12
src/tools/components/Picker.module.scss
Normal file
12
src/tools/components/Picker.module.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
.menuButton {
|
||||
height: auto;
|
||||
text-align: left;
|
||||
|
||||
span:first-child {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.pickerLabel {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { ActionMenu } from '@primer/react'
|
||||
import { AnchorAlignment } from '@primer/behaviors'
|
||||
|
||||
import { Fields } from './Fields'
|
||||
import styles from './Picker.module.scss'
|
||||
|
||||
interface Props {
|
||||
items: PickerItem[]
|
||||
@@ -47,14 +48,9 @@ export const Picker = ({
|
||||
<ActionMenu.Button
|
||||
aria-label={ariaLabel}
|
||||
variant={buttonBorder ? 'default' : 'invisible'}
|
||||
className="color-fg-default width-full p-1 pl-2 pr-2"
|
||||
sx={{
|
||||
height: 'auto',
|
||||
textAlign: 'left',
|
||||
'span:first-child': { display: 'inline' },
|
||||
}}
|
||||
className={`color-fg-default width-full p-1 pl-2 pr-2 ${styles.menuButton}`}
|
||||
>
|
||||
{pickerLabel && <span style={{ whiteSpace: 'pre-wrap' }}>{`${pickerLabel}`}</span>}
|
||||
{pickerLabel && <span className={styles.pickerLabel}>{`${pickerLabel}`}</span>}
|
||||
<span
|
||||
className={`f${descriptionFontSize} color-fg-muted text-normal`}
|
||||
data-testid={dataTestId}
|
||||
|
||||
@@ -157,9 +157,7 @@ export function Webhook({ webhook }: Props) {
|
||||
<Flash className="mb-5" variant="danger">
|
||||
<p>{t('action_type_switch_error')}</p>
|
||||
<p>
|
||||
<code className="f6" style={{ background: 'none' }}>
|
||||
{error.toString()}
|
||||
</code>
|
||||
<code className={`f6 ${styles.errorCode}`}>{error.toString()}</code>
|
||||
</p>
|
||||
</Flash>
|
||||
)}
|
||||
|
||||
@@ -12,3 +12,7 @@
|
||||
padding: 8px 8px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.errorCode {
|
||||
background: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user