mirror of
https://github.com/reactjs/react.dev.git
synced 2026-02-23 20:23:08 +00:00
docs: Adding Social Banner in Support of Ukraine (#4397)
* Adding Social Banner with Support for Ukraine * Changing spacing the social banner * Fixing lint errors * Remove external link icon from social banner * Add banner for beta site * Add todo * Fix centering on mobile in old site Co-authored-by: Rick Hanlon <rickhanlonii@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6c95de96f7
commit
d90fd21fdb
@@ -8,6 +8,7 @@ import {Nav} from './Nav';
|
||||
import {RouteItem, SidebarContext} from './useRouteMeta';
|
||||
import {Sidebar} from './Sidebar';
|
||||
import {Footer} from './Footer';
|
||||
import SocialBanner from '../SocialBanner';
|
||||
interface PageProps {
|
||||
children: React.ReactNode;
|
||||
routeTree: RouteItem;
|
||||
@@ -15,24 +16,27 @@ interface PageProps {
|
||||
|
||||
export function Page({routeTree, children}: PageProps) {
|
||||
return (
|
||||
<MenuProvider>
|
||||
<SidebarContext.Provider value={routeTree}>
|
||||
<div className="h-auto lg:h-screen flex flex-row">
|
||||
<div className="no-bg-scrollbar h-auto lg:h-full lg:overflow-y-scroll fixed flex flex-row lg:flex-col py-0 top-0 left-0 right-0 lg:max-w-xs w-full shadow lg:shadow-none z-50">
|
||||
<Nav />
|
||||
<Sidebar />
|
||||
</div>
|
||||
<>
|
||||
<SocialBanner />
|
||||
<MenuProvider>
|
||||
<SidebarContext.Provider value={routeTree}>
|
||||
<div className="h-auto lg:h-screen flex flex-row">
|
||||
<div className="no-bg-scrollbar h-auto lg:h-full lg:overflow-y-scroll fixed flex flex-row lg:flex-col py-0 top-16 sm:top-10 left-0 right-0 lg:max-w-xs w-full shadow lg:shadow-none z-50">
|
||||
<Nav />
|
||||
<Sidebar />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 w-full h-full self-stretch">
|
||||
<div className="w-full min-w-0">
|
||||
<main className="flex flex-1 self-stretch flex-col items-end justify-around">
|
||||
{children}
|
||||
<Footer />
|
||||
</main>
|
||||
<div className="flex flex-1 w-full h-full self-stretch">
|
||||
<div className="w-full min-w-0">
|
||||
<main className="flex flex-1 self-stretch flex-col items-end justify-around">
|
||||
{children}
|
||||
<Footer />
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarContext.Provider>
|
||||
</MenuProvider>
|
||||
</SidebarContext.Provider>
|
||||
</MenuProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
26
beta/src/components/SocialBanner.tsx
Normal file
26
beta/src/components/SocialBanner.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {ExternalLink} from './ExternalLink';
|
||||
|
||||
// TODO: Unify with the old site settings.
|
||||
// Turning this off also requires changing the Page top value to pull up the sidebar.
|
||||
const bannerText = 'Support Ukraine 🇺🇦';
|
||||
const bannerLink = 'https://opensource.fb.com/support-ukraine';
|
||||
const bannerLinkText = 'Help Provide Humanitarian Aid to Ukraine.';
|
||||
|
||||
export default function SocialBanner() {
|
||||
return (
|
||||
<div className="w-full bg-gray-100 dark:bg-gray-700 sticky py-2 h-16 sm:h-10 sm:py-0 flex items-center justify-center flex-col sm:flex-row">
|
||||
{bannerText}
|
||||
<ExternalLink
|
||||
className="ml-0 sm:ml-1 text-link dark:text-link-dark hover:underline"
|
||||
href={bannerLink}>
|
||||
{bannerLinkText}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -5,7 +5,8 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import Banner from 'components/Banner';
|
||||
import SurveyBanner from 'components/SurveyBanner';
|
||||
import SocialBanner from 'components/SocialBanner';
|
||||
import Container from 'components/Container';
|
||||
import HeaderLink from './HeaderLink';
|
||||
import {Link} from 'gatsby';
|
||||
@@ -46,7 +47,8 @@ const Header = ({location}: {location: Location}) => (
|
||||
<ContainerWrapper>
|
||||
<Container>
|
||||
<div style={{position: 'relative'}}>
|
||||
<Banner />
|
||||
<SurveyBanner />
|
||||
<SocialBanner />
|
||||
</div>
|
||||
</Container>
|
||||
</ContainerWrapper>
|
||||
|
||||
@@ -17,19 +17,23 @@ const MarkdownHeader = ({title}: {title: string}) => {
|
||||
css={{
|
||||
color: colors.dark,
|
||||
marginBottom: 0,
|
||||
marginTop: 'calc(40px + var(--banner-height-normal))',
|
||||
marginTop:
|
||||
'calc(40px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
...fonts.header,
|
||||
|
||||
[media.lessThan('small')]: {
|
||||
marginTop: 'calc(40px + var(--banner-height-small))',
|
||||
marginTop:
|
||||
'calc(40px + var(--survey-banner-height-small) + var(--social-banner-height-small))',
|
||||
},
|
||||
|
||||
[media.size('medium')]: {
|
||||
marginTop: 'calc(60px + var(--banner-height-normal))',
|
||||
marginTop:
|
||||
'calc(60px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
},
|
||||
|
||||
[media.greaterThan('large')]: {
|
||||
marginTop: 'calc(80px + var(--banner-height-normal))',
|
||||
marginTop:
|
||||
'calc(80px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
},
|
||||
}}>
|
||||
{title}
|
||||
|
||||
@@ -75,9 +75,11 @@ const MarkdownPage = ({
|
||||
position: 'relative',
|
||||
zIndex: 0,
|
||||
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
||||
scrollMarginTop: 'var(--banner-height-normal)',
|
||||
scrollMarginTop:
|
||||
'calc(var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
[media.lessThan('small')]: {
|
||||
scrollMarginTop: 'var(--banner-height-small)',
|
||||
scrollMarginTop:
|
||||
'calc(var(--survey-banner-height-small) + var(--social-banner-height-small))',
|
||||
},
|
||||
},
|
||||
}}>
|
||||
|
||||
77
src/components/SocialBanner/SocialBanner.js
Normal file
77
src/components/SocialBanner/SocialBanner.js
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* @emails react-core
|
||||
* @flow
|
||||
*/
|
||||
|
||||
// $FlowFixMe Update Flow
|
||||
import React from 'react';
|
||||
import {colors, fonts, media} from 'theme';
|
||||
import ExternalLinkSvg from 'templates/components/ExternalLinkSvg';
|
||||
|
||||
const linkProps = {
|
||||
href: 'https://opensource.fb.com/support-ukraine',
|
||||
target: '_blank',
|
||||
rel: 'noopener',
|
||||
};
|
||||
|
||||
const bannerText = 'Support Ukraine 🇺🇦 ';
|
||||
const bannerLink = 'Help Provide Humanitarian Aid to Ukraine.';
|
||||
|
||||
export default function SocialBanner() {
|
||||
return (
|
||||
<div
|
||||
css={{
|
||||
display: 'var(--social-banner-display)',
|
||||
height: 'var(--social-banner-height-normal)',
|
||||
fontSize: 18,
|
||||
[media.lessThan('large')]: {
|
||||
fontSize: 16,
|
||||
},
|
||||
[media.lessThan('small')]: {
|
||||
height: 'var(--social-banner-height-small)',
|
||||
fontSize: 14,
|
||||
},
|
||||
}}>
|
||||
<div
|
||||
css={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
}}>
|
||||
<span
|
||||
css={{
|
||||
display: 'flex',
|
||||
[media.lessThan('small')]: {
|
||||
flexDirection: 'column',
|
||||
lineHeight: 1.5,
|
||||
textAlign: 'center',
|
||||
},
|
||||
}}>
|
||||
<span
|
||||
css={{
|
||||
marginRight: '0.5rem',
|
||||
}}>
|
||||
{bannerText}
|
||||
</span>
|
||||
|
||||
<a
|
||||
css={{
|
||||
color: '#ddd',
|
||||
transition: 'color 200ms ease-out',
|
||||
':hover': {
|
||||
color: colors.white,
|
||||
},
|
||||
}}
|
||||
{...linkProps}
|
||||
target="_blank"
|
||||
rel="noopener">
|
||||
<span css={{color: colors.brand}}>{bannerLink}</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,6 @@
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
import Banner from './Banner';
|
||||
import SocialBanner from './SocialBanner';
|
||||
|
||||
export default Banner;
|
||||
export default SocialBanner;
|
||||
@@ -43,7 +43,8 @@ class StickyResponsiveSidebar extends Component<Props, State> {
|
||||
render() {
|
||||
const {open} = this.state;
|
||||
const smallScreenSidebarStyles = {
|
||||
top: 'var(--banner-height-small)',
|
||||
top:
|
||||
'calc(var(--survey-banner-height-small) + var(--social-banner-height-small))',
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
@@ -117,18 +118,21 @@ class StickyResponsiveSidebar extends Component<Props, State> {
|
||||
transition: 'transform 0.5s ease',
|
||||
}}
|
||||
css={{
|
||||
marginTop: 'calc(60px + var(--banner-height-normal))',
|
||||
marginTop:
|
||||
'calc(60px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
|
||||
[media.size('xsmall')]: {
|
||||
marginTop: 40,
|
||||
},
|
||||
|
||||
[media.between('small', 'medium')]: {
|
||||
marginTop: 'calc(20px + var(--banner-height-normal))',
|
||||
marginTop:
|
||||
'calc(20px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
},
|
||||
|
||||
[media.between('medium', 'large')]: {
|
||||
marginTop: 'calc(50px + var(--banner-height-normal))',
|
||||
marginTop:
|
||||
'calc(50px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
|
||||
},
|
||||
|
||||
[media.greaterThan('small')]: {
|
||||
|
||||
@@ -16,18 +16,18 @@ const linkProps = {
|
||||
rel: 'noopener',
|
||||
};
|
||||
|
||||
export default function Banner() {
|
||||
export default function SurveyBanner() {
|
||||
return (
|
||||
<div
|
||||
css={{
|
||||
display: 'var(--banner-display)',
|
||||
height: 'var(--banner-height-normal)',
|
||||
display: 'var(--survey-banner-display)',
|
||||
height: 'var(--survey-banner-height-normal)',
|
||||
fontSize: 18,
|
||||
[media.lessThan('large')]: {
|
||||
fontSize: 16,
|
||||
},
|
||||
[media.lessThan('small')]: {
|
||||
height: 'var(--banner-height-small)',
|
||||
height: 'var(--survey-banner-height-small)',
|
||||
fontSize: 14,
|
||||
},
|
||||
}}>
|
||||
@@ -167,7 +167,7 @@ export default function Banner() {
|
||||
}}
|
||||
onClick={() => {
|
||||
// See html.js
|
||||
window.__dismissBanner();
|
||||
window.__dismissSurveyBanner();
|
||||
}}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
9
src/components/SurveyBanner/index.js
Normal file
9
src/components/SurveyBanner/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
import SurveyBanner from './SurveyBanner';
|
||||
|
||||
export default SurveyBanner;
|
||||
57
src/html.js
57
src/html.js
@@ -51,7 +51,8 @@ export default class HTML extends React.Component<Props> {
|
||||
so it needs to stay compatible with older browsers.
|
||||
*/
|
||||
|
||||
var activeBanner = null;
|
||||
var activeSurveyBanner = null;
|
||||
var socialBanner = null;
|
||||
var snoozeStartDate = null;
|
||||
var today = new Date();
|
||||
|
||||
@@ -61,7 +62,7 @@ export default class HTML extends React.Component<Props> {
|
||||
return time;
|
||||
}
|
||||
|
||||
activeBanner = {
|
||||
activeSurveyBanner = {
|
||||
storageId: 'reactjs_banner_2021survey',
|
||||
normalHeight: 50,
|
||||
smallHeight: 75,
|
||||
@@ -70,11 +71,11 @@ export default class HTML extends React.Component<Props> {
|
||||
snoozeForDays: 7,
|
||||
};
|
||||
|
||||
if (activeBanner) {
|
||||
if (activeSurveyBanner) {
|
||||
try {
|
||||
if (localStorage[activeBanner.storageId]) {
|
||||
if (localStorage[activeSurveyBanner.storageId]) {
|
||||
snoozeStartDate = new Date(
|
||||
parseInt(localStorage.getItem(activeBanner.storageId), 10),
|
||||
parseInt(localStorage.getItem(activeSurveyBanner.storageId), 10),
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -84,44 +85,58 @@ export default class HTML extends React.Component<Props> {
|
||||
try {
|
||||
// If it's too early or long past the campaign, don't show the banner:
|
||||
if (
|
||||
today < new Date(activeBanner.campaignStartDate) ||
|
||||
today > new Date(activeBanner.campaignEndDate)
|
||||
today < new Date(activeSurveyBanner.campaignStartDate) ||
|
||||
today > new Date(activeSurveyBanner.campaignEndDate)
|
||||
) {
|
||||
activeBanner = null;
|
||||
activeSurveyBanner = null;
|
||||
// If we're in the campaign window, but the snooze has been set and it hasn't expired:
|
||||
} else if (
|
||||
snoozeStartDate &&
|
||||
addTimes(snoozeStartDate, activeBanner.snoozeForDays) >= today
|
||||
addTimes(snoozeStartDate, activeSurveyBanner.snoozeForDays) >= today
|
||||
) {
|
||||
activeBanner = null;
|
||||
activeSurveyBanner = null;
|
||||
}
|
||||
} catch (err) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
|
||||
activeSocialBanner = {
|
||||
normalHeight: 50,
|
||||
smallHeight: 75
|
||||
};
|
||||
|
||||
function updateStyles() {
|
||||
if (activeBanner) {
|
||||
document.documentElement.style.setProperty('--banner-display', 'block');
|
||||
document.documentElement.style.setProperty('--banner-height-normal', activeBanner.normalHeight + 'px');
|
||||
document.documentElement.style.setProperty('--banner-height-small', activeBanner.smallHeight + 'px');
|
||||
if (activeSurveyBanner) {
|
||||
document.documentElement.style.setProperty('--survey-banner-display', 'block');
|
||||
document.documentElement.style.setProperty('--survey-banner-height-normal', activeSurveyBanner.normalHeight + 'px');
|
||||
document.documentElement.style.setProperty('--survey-banner-height-small', activeSurveyBanner.smallHeight + 'px');
|
||||
} else {
|
||||
document.documentElement.style.setProperty('--banner-display', 'none');
|
||||
document.documentElement.style.setProperty('--banner-height-normal', '0px');
|
||||
document.documentElement.style.setProperty('--banner-height-small', '0px');
|
||||
document.documentElement.style.setProperty('--survey-banner-display', 'none');
|
||||
document.documentElement.style.setProperty('--survey-banner-height-normal', '0px');
|
||||
document.documentElement.style.setProperty('--survey-banner-height-small', '0px');
|
||||
}
|
||||
if (activeSocialBanner) {
|
||||
document.documentElement.style.setProperty('--social-banner-display', 'block');
|
||||
document.documentElement.style.setProperty('--social-banner-height-normal', activeSocialBanner.normalHeight + 'px');
|
||||
document.documentElement.style.setProperty('--social-banner-height-small', activeSocialBanner.smallHeight + 'px');
|
||||
} else {
|
||||
document.documentElement.style.setProperty('--social-banner-display', 'none');
|
||||
document.documentElement.style.setProperty('--social-banner-height-normal', '0px');
|
||||
document.documentElement.style.setProperty('--social-banner-height-small', '0px');
|
||||
}
|
||||
}
|
||||
|
||||
updateStyles();
|
||||
window.__dismissBanner = function() {
|
||||
if (activeBanner) {
|
||||
window.__dismissSurveyBanner = function() {
|
||||
if (activeSurveyBanner) {
|
||||
try {
|
||||
localStorage.setItem(activeBanner.storageId, Date.now().toString());
|
||||
localStorage.setItem(activeSurveyBanner.storageId, Date.now().toString());
|
||||
} catch (err) {
|
||||
// Ignore.
|
||||
}
|
||||
// Don't show for next navigations within the session.
|
||||
activeBanner = null;
|
||||
activeSurveyBanner = null;
|
||||
updateStyles();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user