Browse Source

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>
main
Dmitry Vinnik | Meta 3 years ago
committed by GitHub
parent
commit
d90fd21fdb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      beta/src/components/Layout/Page.tsx
  2. 26
      beta/src/components/SocialBanner.tsx
  3. 6
      src/components/LayoutHeader/Header.js
  4. 12
      src/components/MarkdownHeader/MarkdownHeader.js
  5. 6
      src/components/MarkdownPage/MarkdownPage.js
  6. 77
      src/components/SocialBanner/SocialBanner.js
  7. 4
      src/components/SocialBanner/index.js
  8. 12
      src/components/StickyResponsiveSidebar/StickyResponsiveSidebar.js
  9. 10
      src/components/SurveyBanner/SurveyBanner.js
  10. 9
      src/components/SurveyBanner/index.js
  11. 57
      src/html.js

36
beta/src/components/Layout/Page.tsx

@ -8,6 +8,7 @@ import {Nav} from './Nav';
import {RouteItem, SidebarContext} from './useRouteMeta'; import {RouteItem, SidebarContext} from './useRouteMeta';
import {Sidebar} from './Sidebar'; import {Sidebar} from './Sidebar';
import {Footer} from './Footer'; import {Footer} from './Footer';
import SocialBanner from '../SocialBanner';
interface PageProps { interface PageProps {
children: React.ReactNode; children: React.ReactNode;
routeTree: RouteItem; routeTree: RouteItem;
@ -15,24 +16,27 @@ interface PageProps {
export function Page({routeTree, children}: PageProps) { export function Page({routeTree, children}: PageProps) {
return ( return (
<MenuProvider> <>
<SidebarContext.Provider value={routeTree}> <SocialBanner />
<div className="h-auto lg:h-screen flex flex-row"> <MenuProvider>
<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"> <SidebarContext.Provider value={routeTree}>
<Nav /> <div className="h-auto lg:h-screen flex flex-row">
<Sidebar /> <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">
</div> <Nav />
<Sidebar />
</div>
<div className="flex flex-1 w-full h-full self-stretch"> <div className="flex flex-1 w-full h-full self-stretch">
<div className="w-full min-w-0"> <div className="w-full min-w-0">
<main className="flex flex-1 self-stretch flex-col items-end justify-around"> <main className="flex flex-1 self-stretch flex-col items-end justify-around">
{children} {children}
<Footer /> <Footer />
</main> </main>
</div>
</div> </div>
</div> </div>
</div> </SidebarContext.Provider>
</SidebarContext.Provider> </MenuProvider>
</MenuProvider> </>
); );
} }

26
beta/src/components/SocialBanner.tsx

@ -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>
);
}

6
src/components/LayoutHeader/Header.js

@ -5,7 +5,8 @@
* @flow * @flow
*/ */
import Banner from 'components/Banner'; import SurveyBanner from 'components/SurveyBanner';
import SocialBanner from 'components/SocialBanner';
import Container from 'components/Container'; import Container from 'components/Container';
import HeaderLink from './HeaderLink'; import HeaderLink from './HeaderLink';
import {Link} from 'gatsby'; import {Link} from 'gatsby';
@ -46,7 +47,8 @@ const Header = ({location}: {location: Location}) => (
<ContainerWrapper> <ContainerWrapper>
<Container> <Container>
<div style={{position: 'relative'}}> <div style={{position: 'relative'}}>
<Banner /> <SurveyBanner />
<SocialBanner />
</div> </div>
</Container> </Container>
</ContainerWrapper> </ContainerWrapper>

12
src/components/MarkdownHeader/MarkdownHeader.js

@ -17,19 +17,23 @@ const MarkdownHeader = ({title}: {title: string}) => {
css={{ css={{
color: colors.dark, color: colors.dark,
marginBottom: 0, marginBottom: 0,
marginTop: 'calc(40px + var(--banner-height-normal))', marginTop:
'calc(40px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
...fonts.header, ...fonts.header,
[media.lessThan('small')]: { [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')]: { [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')]: { [media.greaterThan('large')]: {
marginTop: 'calc(80px + var(--banner-height-normal))', marginTop:
'calc(80px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
}, },
}}> }}>
{title} {title}

6
src/components/MarkdownPage/MarkdownPage.js

@ -75,9 +75,11 @@ const MarkdownPage = ({
position: 'relative', position: 'relative',
zIndex: 0, zIndex: 0,
'& h1, & h2, & h3, & h4, & h5, & h6': { '& 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')]: { [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

@ -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
src/components/Banner/index.js → src/components/SocialBanner/index.js

@ -4,6 +4,6 @@
* @emails react-core * @emails react-core
*/ */
import Banner from './Banner'; import SocialBanner from './SocialBanner';
export default Banner; export default SocialBanner;

12
src/components/StickyResponsiveSidebar/StickyResponsiveSidebar.js

@ -43,7 +43,8 @@ class StickyResponsiveSidebar extends Component<Props, State> {
render() { render() {
const {open} = this.state; const {open} = this.state;
const smallScreenSidebarStyles = { const smallScreenSidebarStyles = {
top: 'var(--banner-height-small)', top:
'calc(var(--survey-banner-height-small) + var(--social-banner-height-small))',
left: 0, left: 0,
bottom: 0, bottom: 0,
right: 0, right: 0,
@ -117,18 +118,21 @@ class StickyResponsiveSidebar extends Component<Props, State> {
transition: 'transform 0.5s ease', transition: 'transform 0.5s ease',
}} }}
css={{ css={{
marginTop: 'calc(60px + var(--banner-height-normal))', marginTop:
'calc(60px + var(--survey-banner-height-normal) + var(--social-banner-height-normal))',
[media.size('xsmall')]: { [media.size('xsmall')]: {
marginTop: 40, marginTop: 40,
}, },
[media.between('small', 'medium')]: { [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')]: { [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')]: { [media.greaterThan('small')]: {

10
src/components/Banner/Banner.js → src/components/SurveyBanner/SurveyBanner.js

@ -16,18 +16,18 @@ const linkProps = {
rel: 'noopener', rel: 'noopener',
}; };
export default function Banner() { export default function SurveyBanner() {
return ( return (
<div <div
css={{ css={{
display: 'var(--banner-display)', display: 'var(--survey-banner-display)',
height: 'var(--banner-height-normal)', height: 'var(--survey-banner-height-normal)',
fontSize: 18, fontSize: 18,
[media.lessThan('large')]: { [media.lessThan('large')]: {
fontSize: 16, fontSize: 16,
}, },
[media.lessThan('small')]: { [media.lessThan('small')]: {
height: 'var(--banner-height-small)', height: 'var(--survey-banner-height-small)',
fontSize: 14, fontSize: 14,
}, },
}}> }}>
@ -167,7 +167,7 @@ export default function Banner() {
}} }}
onClick={() => { onClick={() => {
// See html.js // See html.js
window.__dismissBanner(); window.__dismissSurveyBanner();
}}> }}>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

9
src/components/SurveyBanner/index.js

@ -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

@ -51,7 +51,8 @@ export default class HTML extends React.Component<Props> {
so it needs to stay compatible with older browsers. so it needs to stay compatible with older browsers.
*/ */
var activeBanner = null; var activeSurveyBanner = null;
var socialBanner = null;
var snoozeStartDate = null; var snoozeStartDate = null;
var today = new Date(); var today = new Date();
@ -61,7 +62,7 @@ export default class HTML extends React.Component<Props> {
return time; return time;
} }
activeBanner = { activeSurveyBanner = {
storageId: 'reactjs_banner_2021survey', storageId: 'reactjs_banner_2021survey',
normalHeight: 50, normalHeight: 50,
smallHeight: 75, smallHeight: 75,
@ -70,11 +71,11 @@ export default class HTML extends React.Component<Props> {
snoozeForDays: 7, snoozeForDays: 7,
}; };
if (activeBanner) { if (activeSurveyBanner) {
try { try {
if (localStorage[activeBanner.storageId]) { if (localStorage[activeSurveyBanner.storageId]) {
snoozeStartDate = new Date( snoozeStartDate = new Date(
parseInt(localStorage.getItem(activeBanner.storageId), 10), parseInt(localStorage.getItem(activeSurveyBanner.storageId), 10),
); );
} }
} catch (err) { } catch (err) {
@ -84,44 +85,58 @@ export default class HTML extends React.Component<Props> {
try { try {
// If it's too early or long past the campaign, don't show the banner: // If it's too early or long past the campaign, don't show the banner:
if ( if (
today < new Date(activeBanner.campaignStartDate) || today < new Date(activeSurveyBanner.campaignStartDate) ||
today > new Date(activeBanner.campaignEndDate) 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: // If we're in the campaign window, but the snooze has been set and it hasn't expired:
} else if ( } else if (
snoozeStartDate && snoozeStartDate &&
addTimes(snoozeStartDate, activeBanner.snoozeForDays) >= today addTimes(snoozeStartDate, activeSurveyBanner.snoozeForDays) >= today
) { ) {
activeBanner = null; activeSurveyBanner = null;
} }
} catch (err) { } catch (err) {
// Ignore. // Ignore.
} }
} }
activeSocialBanner = {
normalHeight: 50,
smallHeight: 75
};
function updateStyles() { function updateStyles() {
if (activeBanner) { if (activeSurveyBanner) {
document.documentElement.style.setProperty('--banner-display', 'block'); document.documentElement.style.setProperty('--survey-banner-display', 'block');
document.documentElement.style.setProperty('--banner-height-normal', activeBanner.normalHeight + 'px'); document.documentElement.style.setProperty('--survey-banner-height-normal', activeSurveyBanner.normalHeight + 'px');
document.documentElement.style.setProperty('--banner-height-small', activeBanner.smallHeight + 'px'); document.documentElement.style.setProperty('--survey-banner-height-small', activeSurveyBanner.smallHeight + 'px');
} else {
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 { } else {
document.documentElement.style.setProperty('--banner-display', 'none'); document.documentElement.style.setProperty('--social-banner-display', 'none');
document.documentElement.style.setProperty('--banner-height-normal', '0px'); document.documentElement.style.setProperty('--social-banner-height-normal', '0px');
document.documentElement.style.setProperty('--banner-height-small', '0px'); document.documentElement.style.setProperty('--social-banner-height-small', '0px');
} }
} }
updateStyles(); updateStyles();
window.__dismissBanner = function() { window.__dismissSurveyBanner = function() {
if (activeBanner) { if (activeSurveyBanner) {
try { try {
localStorage.setItem(activeBanner.storageId, Date.now().toString()); localStorage.setItem(activeSurveyBanner.storageId, Date.now().toString());
} catch (err) { } catch (err) {
// Ignore. // Ignore.
} }
// Don't show for next navigations within the session. // Don't show for next navigations within the session.
activeBanner = null; activeSurveyBanner = null;
updateStyles(); updateStyles();
} }
}; };

Loading…
Cancel
Save