Browse Source

Merge pull request #205 from tricinel/feature/flow-types

Add flow types to components; realted to #24
main
Brian Vaughn 8 years ago
committed by GitHub
parent
commit
b8d13d5fe5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      flow-typed/glamor.js
  2. 11
      flow-typed/polyfills.js
  3. 3
      flow-typed/slugify.js
  4. 17
      src/components/Flex/Flex.js
  5. 12
      src/components/LayoutFooter/ExternalFooterLink.js
  6. 3
      src/components/LayoutFooter/Footer.js
  7. 11
      src/components/LayoutFooter/FooterLink.js
  8. 11
      src/components/LayoutFooter/FooterNav.js
  9. 7
      src/components/LayoutHeader/DocSearch.js
  10. 3
      src/components/LayoutHeader/Header.js
  11. 9
      src/components/LayoutHeader/HeaderLink.js
  12. 31
      src/components/StickyResponsiveSidebar/StickyResponsiveSidebar.js
  13. 8
      src/layouts/index.js
  14. 2
      src/pages/blog/all.html.js
  15. 8
      src/pages/docs/error-decoder.html.js
  16. 38
      src/utils/createLink.js
  17. 3
      src/utils/createOgUrl.js
  18. 16
      src/utils/findSectionForPath.js
  19. 10
      src/utils/isItemActive.js
  20. 8
      src/utils/sectionList.js
  21. 3
      src/utils/slugify.js
  22. 10
      src/utils/toCommaSeparatedList.js

14
flow-typed/glamor.js

@ -5,3 +5,17 @@ declare module 'glamor' {
}, },
}; };
} }
declare module 'glamor/react' {
declare module.exports: {
createElement: any,
dom: any,
vars: any,
makeTheme: any,
propMerge: Function,
};
}
declare module 'glamor/reset' {
declare module.exports: any;
}

11
flow-typed/polyfills.js

@ -0,0 +1,11 @@
declare module 'array-from' {
declare module.exports: any;
}
declare module 'string.prototype.includes' {
declare module.exports: any;
}
declare module 'string.prototype.repeat' {
declare module.exports: any;
}

3
flow-typed/slugify.js

@ -0,0 +1,3 @@
declare module 'slugify' {
declare module.exports: any;
}

17
src/components/Flex/Flex.js

@ -2,12 +2,27 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
import {createElement} from 'glamor/react'; import {createElement} from 'glamor/react';
import type {Node} from 'react';
type Props = {
basis: string,
children: Node,
direction: string,
grow: number,
halign: string,
shrink: number,
type: string,
valign: string,
rest: Array<any>,
};
/** /**
* Convenience component for declaring a flexbox layout. * Convenience component for declaring a flexbox layout.
*/ */
@ -21,7 +36,7 @@ const Flex = ({
type = 'div', type = 'div',
valign = 'flex-start', valign = 'flex-start',
...rest ...rest
}) => }: Props) =>
createElement( createElement(
type, type,
{ {

12
src/components/LayoutFooter/ExternalFooterLink.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -10,7 +11,16 @@ import React from 'react';
import {colors} from 'theme'; import {colors} from 'theme';
import ExternalLinkSvg from 'templates/components/ExternalLinkSvg'; import ExternalLinkSvg from 'templates/components/ExternalLinkSvg';
const ExternalFooterLink = ({children, href, target, rel}) => ( import type {Node} from 'react';
type Props = {
children: Node,
href: string,
target?: string,
rel?: string,
};
const ExternalFooterLink = ({children, href, target, rel}: Props) => (
<a <a
css={{ css={{
lineHeight: 2, lineHeight: 2,

3
src/components/LayoutFooter/Footer.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -16,7 +17,7 @@ import {colors, media} from 'theme';
import ossLogoPng from 'images/oss_logo.png'; import ossLogoPng from 'images/oss_logo.png';
const Footer = ({layoutHasSidebar = false}) => ( const Footer = ({layoutHasSidebar = false}: {layoutHasSidebar: boolean}) => (
<footer <footer
css={{ css={{
backgroundColor: colors.darker, backgroundColor: colors.darker,

11
src/components/LayoutFooter/FooterLink.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -10,7 +11,15 @@ import Link from 'gatsby-link';
import React from 'react'; import React from 'react';
import {colors} from 'theme'; import {colors} from 'theme';
const FooterLink = ({children, target, to}) => ( import type {Node} from 'react';
type Props = {
children: Node,
target?: string,
to: string,
};
const FooterLink = ({children, target, to}: Props) => (
<Link <Link
css={{ css={{
lineHeight: 2, lineHeight: 2,

11
src/components/LayoutFooter/FooterNav.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -9,7 +10,15 @@
import React from 'react'; import React from 'react';
import {media} from 'theme'; import {media} from 'theme';
const FooterNav = ({children, title, layoutHasSidebar = false}) => ( import type {Node} from 'react';
type Props = {
children: Node,
title?: string,
layoutHasSidebar: boolean,
};
const FooterNav = ({children, title, layoutHasSidebar = false}: Props) => (
<div <div
css={{ css={{
display: 'flex', display: 'flex',

7
src/components/LayoutHeader/DocSearch.js

@ -2,12 +2,17 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
import React, {Component} from 'react'; import React, {Component} from 'react';
import {colors, media} from 'theme'; import {colors, media} from 'theme';
class DocSearch extends Component { type State = {
enabled: boolean,
};
class DocSearch extends Component<{}, State> {
state = { state = {
enabled: true, enabled: true,
}; };

3
src/components/LayoutHeader/Header.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -17,7 +18,7 @@ import DocSearch from './DocSearch';
import logoSvg from 'icons/logo.svg'; import logoSvg from 'icons/logo.svg';
const Header = ({location}) => ( const Header = ({location}: {location: Location}) => (
<header <header
css={{ css={{
backgroundColor: colors.darker, backgroundColor: colors.darker,

9
src/components/LayoutHeader/HeaderLink.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -10,7 +11,13 @@ import Link from 'gatsby-link';
import React from 'react'; import React from 'react';
import {colors, media} from 'theme'; import {colors, media} from 'theme';
const HeaderLink = ({isActive, title, to}) => ( type Props = {
isActive: boolean,
title: string,
to: string,
};
const HeaderLink = ({isActive, title, to}: Props) => (
<Link css={[style, isActive && activeStyle]} to={to}> <Link css={[style, isActive && activeStyle]} to={to}>
{title} {title}
{isActive && <span css={activeAfterStyle} />} {isActive && <span css={activeAfterStyle} />}

31
src/components/StickyResponsiveSidebar/StickyResponsiveSidebar.js

@ -2,34 +2,45 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
import Container from 'components/Container'; import Container from 'components/Container';
import {Component, React} from 'react'; import React, {Component} from 'react';
import Sidebar from 'templates/components/Sidebar'; import Sidebar from 'templates/components/Sidebar';
import {colors, media} from 'theme'; import {colors, media} from 'theme';
import ChevronSvg from 'templates/components/ChevronSvg'; import ChevronSvg from 'templates/components/ChevronSvg';
class StickyResponsiveSidebar extends Component { type State = {
constructor(props, context) { open: boolean,
super(props, context); };
type Props = {
enableScrollSync?: boolean,
createLink: Function, // TODO: Add better flow type once we Flow-type createLink
defaultActiveSection: string,
location: Location,
sectionList: Array<Object>, // TODO: Add better flow type once we have the Section component
};
class StickyResponsiveSidebar extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { this.state = {
open: false, open: false,
}; };
this._openNavMenu = this._openNavMenu.bind(this);
this._closeNavMenu = this._closeNavMenu.bind(this);
} }
_openNavMenu() { _openNavMenu = () => {
this.setState({open: !this.state.open}); this.setState({open: !this.state.open});
} };
_closeNavMenu() { _closeNavMenu = () => {
this.setState({open: false}); this.setState({open: false});
} };
render() { render() {
const {open} = this.state; const {open} = this.state;

8
src/layouts/index.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -23,7 +24,12 @@ import 'glamor/reset';
import 'css/reset.css'; import 'css/reset.css';
import 'css/algolia.css'; import 'css/algolia.css';
class Template extends Component { type Props = {
children: Function,
location: Location,
};
class Template extends Component<Props> {
render() { render() {
const {children, location} = this.props; const {children, location} = this.props;

2
src/pages/blog/all.html.js

@ -76,6 +76,7 @@ const AllBlogPosts = ({data}: Props) => (
</Link> </Link>
</h2> </h2>
<MetaTitle>{node.fields.date}</MetaTitle> <MetaTitle>{node.fields.date}</MetaTitle>
{node.frontmatter.author ? (
<div <div
css={{ css={{
color: colors.subtle, color: colors.subtle,
@ -88,6 +89,7 @@ const AllBlogPosts = ({data}: Props) => (
</span> </span>
))} ))}
</div> </div>
) : null}
</li> </li>
))} ))}
</ul> </ul>

8
src/pages/docs/error-decoder.html.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -19,7 +20,12 @@ import {createLinkDocs} from 'utils/createLink';
import findSectionForPath from 'utils/findSectionForPath'; import findSectionForPath from 'utils/findSectionForPath';
import {sectionListDocs} from 'utils/sectionList'; import {sectionListDocs} from 'utils/sectionList';
const ErrorPage = ({data, location}) => ( type Props = {
data: Object,
location: Location,
};
const ErrorPage = ({data, location}: Props) => (
<Flex <Flex
direction="column" direction="column"
grow="1" grow="1"

38
src/utils/createLink.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -12,7 +13,19 @@ import ExternalLinkSvg from 'templates/components/ExternalLinkSvg';
import slugify from 'utils/slugify'; import slugify from 'utils/slugify';
import {colors, media} from 'theme'; import {colors, media} from 'theme';
const createLinkBlog = ({isActive, item, section}) => { import type {Node} from 'react';
type CreateLinkBaseProps = {
isActive: boolean,
item: Object,
section: Object,
};
const createLinkBlog = ({
isActive,
item,
section,
}: CreateLinkBaseProps): Node => {
return ( return (
<Link css={[linkCss, isActive && activeLinkCss]} to={item.id}> <Link css={[linkCss, isActive && activeLinkCss]} to={item.id}>
{isActive && <span css={activeLinkBefore} />} {isActive && <span css={activeLinkBefore} />}
@ -21,7 +34,11 @@ const createLinkBlog = ({isActive, item, section}) => {
); );
}; };
const createLinkCommunity = ({isActive, item, section}) => { const createLinkCommunity = ({
isActive,
item,
section,
}: CreateLinkBaseProps): Node => {
if (item.href) { if (item.href) {
return ( return (
<a css={[linkCss]} href={item.href} target="_blank" rel="noopener"> <a css={[linkCss]} href={item.href} target="_blank" rel="noopener">
@ -44,7 +61,11 @@ const createLinkCommunity = ({isActive, item, section}) => {
}); });
}; };
const createLinkDocs = ({isActive, item, section}) => { const createLinkDocs = ({
isActive,
item,
section,
}: CreateLinkBaseProps): Node => {
return ( return (
<Link <Link
css={[linkCss, isActive && activeLinkCss]} css={[linkCss, isActive && activeLinkCss]}
@ -55,7 +76,16 @@ const createLinkDocs = ({isActive, item, section}) => {
); );
}; };
const createLinkTutorial = ({isActive, item, onLinkClick, section}) => { type CreateLinkTutorialProps = {
onLinkClick: Function,
} & CreateLinkBaseProps;
const createLinkTutorial = ({
isActive,
item,
onLinkClick,
section,
}: CreateLinkTutorialProps): Node => {
return ( return (
<Link <Link
css={[linkCss, isActive && activeLinkCss]} css={[linkCss, isActive && activeLinkCss]}

3
src/utils/createOgUrl.js

@ -2,11 +2,12 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
import {urlRoot} from 'site-constants'; import {urlRoot} from 'site-constants';
export default slug => export default (slug: string): string | null =>
slug == null ? null : `${urlRoot}/${slug.replace(/^\//, '')}`; slug == null ? null : `${urlRoot}/${slug.replace(/^\//, '')}`;

16
src/utils/findSectionForPath.js

@ -2,6 +2,7 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
@ -12,7 +13,20 @@ import slugify from './slugify';
* Helper method to locate the section containing the current URL/path. * Helper method to locate the section containing the current URL/path.
* This method specifically works with the nav_*.yml format. * This method specifically works with the nav_*.yml format.
*/ */
const findSectionForPath = (pathname, sections) => {
type Item = {
id: string,
subitems: Array<Item>,
};
type Section = {
items: Array<Item>,
};
const findSectionForPath = (
pathname: string,
sections: Array<Section>,
): Section | void => {
let activeSection; let activeSection;
const slugId = pathname.split('/').slice(-1)[0]; const slugId = pathname.split('/').slice(-1)[0];

10
src/utils/isItemActive.js

@ -2,13 +2,14 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
import slugify from 'utils/slugify'; import slugify from 'utils/slugify';
const toAnchor = (href = '') => { const toAnchor = (href: string = ''): string => {
const index = href.indexOf('#'); const index = href.indexOf('#');
return index >= 0 ? href.substr(index) : ''; return index >= 0 ? href.substr(index) : '';
}; };
@ -16,7 +17,12 @@ const toAnchor = (href = '') => {
// TODO Account for redirect_from URLs somehow; they currently won't match. // TODO Account for redirect_from URLs somehow; they currently won't match.
// This comment should not be true anymore since we're using 300 redirects // This comment should not be true anymore since we're using 300 redirects
const isItemActive = (location, item) => { type Item = {
id: string,
href: string,
};
const isItemActive = (location: Location, item: Item): boolean => {
if (location.hash) { if (location.hash) {
if (item.href) { if (item.href) {
return location.hash === toAnchor(item.href); return location.hash === toAnchor(item.href);

8
src/utils/sectionList.js

@ -2,20 +2,24 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
// $FlowExpectedError
import navCommunity from '../../content/community/nav.yml'; import navCommunity from '../../content/community/nav.yml';
// $FlowExpectedError
import navDocs from '../../content/docs/nav.yml'; import navDocs from '../../content/docs/nav.yml';
// $FlowExpectedError
import navTutorial from '../../content/tutorial/nav.yml'; import navTutorial from '../../content/tutorial/nav.yml';
const sectionListDocs = navDocs.map(item => ({ const sectionListDocs = navDocs.map((item: Object): Object => ({
...item, ...item,
directory: 'docs', directory: 'docs',
})); }));
const sectionListCommunity = navCommunity.map(item => ({ const sectionListCommunity = navCommunity.map((item: Object): Object => ({
...item, ...item,
directory: 'community', directory: 'community',
})); }));

3
src/utils/slugify.js

@ -2,13 +2,14 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
import slugify from 'slugify'; import slugify from 'slugify';
export default (string, directory) => { export default (string: string, directory?: string): string => {
const filename = slugify(string) + '.html'; const filename = slugify(string) + '.html';
return directory ? `/${directory}/${filename}` : filename; return directory ? `/${directory}/${filename}` : filename;

10
src/utils/toCommaSeparatedList.js

@ -2,16 +2,22 @@
* Copyright (c) 2013-present, Facebook, Inc. * Copyright (c) 2013-present, Facebook, Inc.
* *
* @emails react-core * @emails react-core
* @flow
*/ */
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
const addString = (list, string) => import type {Node} from 'react';
const addString = (list: Array<Node>, string: string) =>
list.push(<span key={`${list.length}-${string}`}>{string}</span>); list.push(<span key={`${list.length}-${string}`}>{string}</span>);
const toCommaSeparatedList = (array, renderCallback) => { const toCommaSeparatedList = (
array: Array<any>,
renderCallback: Function,
): Array<any> => {
if (array.length <= 1) { if (array.length <= 1) {
return array.map(renderCallback); return array.map(renderCallback);
} }

Loading…
Cancel
Save