@primer/blueprints
Advanced tools
Comparing version 0.0.0-d9dc9d0 to 0.0.0-ec20941
@@ -7,2 +7,3 @@ import React, { useEffect, useState } from 'react'; | ||
import TreeModel from 'tree-model'; | ||
import { join } from 'path'; | ||
import Measure from 'react-measure'; | ||
@@ -16,3 +17,2 @@ import HTMLtoJSX from 'html-2-jsx'; | ||
import { withRouter } from 'next/router'; | ||
import { join } from 'path'; | ||
@@ -414,2 +414,29 @@ function _classCallCheck(instance, Constructor) { | ||
function sortCompare(a, b, get) { | ||
var aa = get(a); | ||
var bb = get(b); | ||
return typeof aa === 'string' && typeof bb === 'string' ? aa.localeCompare(bb) : undefined; | ||
} | ||
function nodeSort(a, b) { | ||
return sortCompare(a, b, function (node) { | ||
return node.meta.sort_title || node.meta.title; | ||
}); | ||
} | ||
function addPath(el, path) { | ||
// if there's no path, just return the element | ||
if (!path) return el; // if this is a link it'll have an "href"; otherwise, add "path" | ||
var prop = el.props.href ? 'href' : 'path'; | ||
var value = el.props[prop]; | ||
var props = {}; // if there's a value and it's not absolute, prefix it with the path | ||
if (value && !value.match(/^(\/|https?:)/)) { | ||
props[prop] = join(path, value); | ||
} else { | ||
props[prop] = path; | ||
} | ||
return React.cloneElement(el, props); | ||
} | ||
var Frame = | ||
@@ -785,3 +812,3 @@ /*#__PURE__*/ | ||
/** | ||
* The NodeLink component takes an `href` and optional `children`. | ||
* The PageLink component takes an `href` and optional `children`. | ||
* If no `children` are provided, we look up the "node" of the corresponding | ||
@@ -798,11 +825,11 @@ * page in the tree (the one whose `path` matches the given `href`) and use | ||
* | ||
* The following instance of NodeLink should render a link to "/foo/bar" with | ||
* The following instance of PageLink should render a link to "/foo/bar" with | ||
* "Foo Bar" as its text: | ||
* | ||
* ```jsx | ||
* <NodeLink href="/foo/bar" /> | ||
* <PageLink href="/foo/bar" /> | ||
* ``` | ||
*/ | ||
function NodeLink(props) { | ||
function PageLink(props) { | ||
var href = props.href, | ||
@@ -821,19 +848,92 @@ content = props.children; | ||
} | ||
NodeLink.displayName = "NodeLink"; | ||
PageLink.displayName = "PageLink"; | ||
var NavLink = withRouter(function (_ref) { | ||
var _ref$is = _ref.is, | ||
Tag = _ref$is === void 0 ? NodeLink : _ref$is, | ||
href = _ref.href, | ||
var href = _ref.href, | ||
router = _ref.router, | ||
rest = _objectWithoutProperties(_ref, ["is", "href", "router"]); | ||
rest = _objectWithoutProperties(_ref, ["href", "router"]); | ||
return React.createElement(Tag, _extends({ | ||
return React.createElement(Box, rest, React.createElement(PageLink, _extends({ | ||
href: href, | ||
color: "white", | ||
px: 4, | ||
fontWeight: router.pathname === href ? 'bold' : null | ||
}, rest)); | ||
color: router.pathname === href ? 'black' : undefined, | ||
fontSize: 1 | ||
}, rest))); | ||
}); | ||
/** | ||
* A <Section> gets a `path` and optional children. If it has children it will | ||
* render those and prepend each child's `href` prop with the provided `path`. | ||
* This means that you can do: | ||
* | ||
* ```jsx | ||
* <Section path="/section"> | ||
* <Link href="foo">Links to /section/foo</Link> | ||
* </Section> | ||
* ``` | ||
* | ||
* If no children are provided, it renders a <NavList> with the provided | ||
* `path`. | ||
*/ | ||
var Section = function Section(_ref) { | ||
var path = _ref.path, | ||
children = _ref.children; | ||
return React.createElement(BorderBox, { | ||
p: 5, | ||
border: 0, | ||
borderBottom: 1, | ||
borderRadius: 0, | ||
width: "100%" | ||
}, children && path ? React.Children.map(children, function (child) { | ||
return addPath(child, path); | ||
}) : React.createElement(NavList, { | ||
path: path | ||
})); | ||
}; | ||
Section.displayName = "Section"; | ||
/** | ||
* A <Section.Link> is really just a <PageLink> that's bold when its `href` | ||
* matches the current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
var SectionLink = withRouter(function (_ref2) { | ||
var href = _ref2.href, | ||
router = _ref2.router, | ||
rest = _objectWithoutProperties(_ref2, ["href", "router"]); | ||
return React.createElement(Box, rest, React.createElement(PageLink, _extends({ | ||
href: href | ||
}, rest, { | ||
fontSize: 2, | ||
fontWeight: router.pathname.startsWith(href) ? 'bold' : null | ||
}))); | ||
}); | ||
Section.Link = SectionLink; | ||
/** | ||
* A <NavList> renders a <Section.Link> for the given `path` and looks up the | ||
* path in the page tree. If a node is found, it renders a <NavLink> for each | ||
* of the node's children. | ||
*/ | ||
function NavList(_ref) { | ||
var path = _ref.path; | ||
var node = rootPage.first(function (node) { | ||
return node.path === path; | ||
}); | ||
var children = node ? node.children.sort(nodeSort) : []; | ||
return React.createElement(React.Fragment, null, React.createElement(Section.Link, { | ||
color: "gray.9", | ||
href: path, | ||
mb: 3 | ||
}), children.map(function (child) { | ||
return React.createElement(NavLink, { | ||
mt: 2, | ||
href: child.path, | ||
key: child.path | ||
}); | ||
})); | ||
} | ||
function Outline(_ref) { | ||
@@ -976,108 +1076,24 @@ var outline = _ref.outline, | ||
function SideNav(props) { | ||
return React.createElement(Relative, { | ||
is: "nav" | ||
}, React.createElement(Box, _extends({ | ||
id: "sidenav" | ||
}, props), React.createElement(Flex, { | ||
flexDirection: "column", | ||
alignItems: "start" | ||
}, React.createElement(Router, null, React.createElement(RouteMatch, { | ||
path: "/blueprints" | ||
}, React.createElement(Section, { | ||
path: "components" | ||
})))))); | ||
} | ||
SideNav.displayName = "SideNav"; | ||
/** | ||
* A <Section> gets a `path` and optional children. If it has children it will | ||
* render those and prepend each child's `href` prop with the provided `path`. | ||
* This means that you can do: | ||
* <RouteMatch> is just a way to conditionally render content without a wrapper | ||
* element when contained directly in a <Router>: | ||
* | ||
* ```jsx | ||
* <Section path="/section"> | ||
* <Link href="foo">Links to /section/foo</Link> | ||
* </Section> | ||
* <Router> | ||
* <RouteMatch path="/some/dir"> | ||
* this will only show up on pages whose path begins with "/some/dir" | ||
* </RouteMatch> | ||
* </Router> | ||
* ``` | ||
* | ||
* If no children are provided, it renders a <NavList> with the provided | ||
* `path`. | ||
*/ | ||
var Section = function Section(_ref) { | ||
function RouteMatch(_ref) { | ||
var path = _ref.path, | ||
children = _ref.children; | ||
return React.createElement(BorderBox, { | ||
p: 5, | ||
border: 0, | ||
borderBottom: 1, | ||
borderRadius: 0, | ||
width: "100%" | ||
}, children && path ? React.Children.map(children, function (child) { | ||
return path ? React.Children.map(children, function (child) { | ||
return addPath(child, path); | ||
}) : React.createElement(NavList, { | ||
path: path | ||
})); | ||
}; | ||
Section.displayName = "Section"; | ||
/** | ||
* A <NavList> renders a <SectionLink> for the given `path` and looks up the | ||
* path in the page tree. If a node is found, it renders a <NavLink> for each | ||
* of the node's children. | ||
*/ | ||
function NavList(_ref2) { | ||
var path = _ref2.path; | ||
var node = rootPage.first(function (node) { | ||
return node.path === path; | ||
}); | ||
var children = node ? node.children.sort(nodeSort) : []; | ||
return React.createElement(React.Fragment, null, React.createElement(SectionLink, { | ||
href: path, | ||
mb: 3 | ||
}), children.map(function (child) { | ||
return React.createElement(NavLink$1, { | ||
href: child.path, | ||
key: child.path | ||
}); | ||
})); | ||
}) : children; | ||
} | ||
/** | ||
* A <SectionLink> is really just a <NodeLink> that's bold when its `href` | ||
* matches the current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
var SectionLink = withRouter(function (_ref3) { | ||
var href = _ref3.href, | ||
router = _ref3.router, | ||
rest = _objectWithoutProperties(_ref3, ["href", "router"]); | ||
return React.createElement(Box, rest, React.createElement(NodeLink, { | ||
href: href, | ||
color: "gray.9", | ||
fontSize: 2, | ||
fontWeight: router.pathname.startsWith(href) ? 'bold' : null | ||
})); | ||
}); | ||
/** | ||
* A <NavLink> is a <NodeLink> that turns black when its `href` matches the | ||
* current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
var NavLink$1 = withRouter(function (_ref4) { | ||
var href = _ref4.href, | ||
router = _ref4.router, | ||
rest = _objectWithoutProperties(_ref4, ["href", "router"]); | ||
return React.createElement(Box, { | ||
mt: 2 | ||
}, React.createElement(NodeLink, _extends({ | ||
href: href, | ||
color: router.pathname === href ? 'black' : undefined, | ||
fontSize: 1 | ||
}, rest))); | ||
}); | ||
/** | ||
* This is inspired by React Router's <Router> component, in that it looks for | ||
@@ -1089,5 +1105,5 @@ * children with the `path` prop and only renders the _first_ one that matches | ||
var Router = withRouter(function (_ref5) { | ||
var router = _ref5.router, | ||
children = _ref5.children; | ||
var Router = withRouter(function (_ref) { | ||
var router = _ref.router, | ||
children = _ref.children; | ||
var matched = false; | ||
@@ -1104,52 +1120,16 @@ return React.Children.toArray(children).map(function (child) { | ||
}); | ||
/** | ||
* <RouteMatch> is just a way to conditionally render content without a wrapper | ||
* element when contained directly in a <Router>: | ||
* | ||
* ```jsx | ||
* <Router> | ||
* <RouteMatch path="/some/dir"> | ||
* this will only show up on pages whose path begins with "/some/dir" | ||
* </RouteMatch> | ||
* </Router> | ||
* ``` | ||
*/ | ||
function RouteMatch(_ref6) { | ||
var path = _ref6.path, | ||
children = _ref6.children; | ||
return path ? React.Children.map(children, function (child) { | ||
return addPath(child, path); | ||
}) : children; | ||
function SideNav(props) { | ||
return React.createElement(Relative, { | ||
is: "nav" | ||
}, React.createElement(Box, _extends({ | ||
id: "sidenav" | ||
}, props), React.createElement(Flex, { | ||
flexDirection: "column", | ||
alignItems: "start" | ||
}, React.createElement(Router, null, props.children)))); | ||
} | ||
function sortCompare(a, b, get) { | ||
var aa = get(a); | ||
var bb = get(b); | ||
return typeof aa === 'string' && typeof bb === 'string' ? aa.localeCompare(bb) : undefined; | ||
} | ||
SideNav.displayName = "SideNav"; | ||
function nodeSort(a, b) { | ||
return sortCompare(a, b, function (node) { | ||
return node.meta.sort_title || node.meta.title; | ||
}); | ||
} | ||
function addPath(el, path) { | ||
// if there's no path, just return the element | ||
if (!path) return el; // if this is a link it'll have an "href"; otherwise, add "path" | ||
var prop = el.props.href ? 'href' : 'path'; | ||
var value = el.props[prop]; | ||
var props = {}; // if there's a value and it's not absolute, prefix it with the path | ||
if (value && !value.match(/^(\/|https?:)/)) { | ||
props[prop] = join(path, value); | ||
} else { | ||
props[prop] = path; | ||
} | ||
return React.cloneElement(el, props); | ||
} | ||
export { ClipboardCopy, CodeExample, Contributors, Frame, Header, Link$1 as Link, NavLink, NodeLink, Outline, PackageHeader, SideNav, StatusLabel, CommonStyles, CommonScripts, config, assetPrefix, assetPath, getAssetPath, requirePage, pathMap, pageTree, rootPage }; | ||
export { ClipboardCopy, CodeExample, Contributors, Frame, Header, Link$1 as Link, NavLink, NavList, Outline, PackageHeader, PageLink, RouteMatch, Router, Section, SideNav, StatusLabel, CommonStyles, CommonScripts, config, assetPrefix, assetPath, getAssetPath, requirePage, pathMap, pageTree, rootPage, sortCompare, nodeSort, addPath }; |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('react-dom'), require('@primer/components'), require('@githubprimer/octicons-react'), require('next/config'), require('tree-model'), require('react-measure'), require('html-2-jsx'), require('react-live'), require('prism-github/prism-github.scss'), require('prop-types'), require('next/link'), require('styled-components'), require('next/router'), require('path')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'react', 'react-dom', '@primer/components', '@githubprimer/octicons-react', 'next/config', 'tree-model', 'react-measure', 'html-2-jsx', 'react-live', 'prism-github/prism-github.scss', 'prop-types', 'next/link', 'styled-components', 'next/router', 'path'], factory) : | ||
(factory((global.primer = {}),global.React,global.ReactDOM,global.components,global.Octicon,global.getConfig,global.TreeModel,global.Measure,global.HTMLtoJSX,global.reactLive,null,global.propTypes,global.NextLink,global.styled,global.router,global.path)); | ||
}(this, (function (exports,React,ReactDOM,components,Octicon,getConfig,TreeModel,Measure,HTMLtoJSX,reactLive,prismGithub_scss,propTypes,NextLink,styled,router,path) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('react-dom'), require('@primer/components'), require('@githubprimer/octicons-react'), require('next/config'), require('tree-model'), require('path'), require('react-measure'), require('html-2-jsx'), require('react-live'), require('prism-github/prism-github.scss'), require('prop-types'), require('next/link'), require('styled-components'), require('next/router')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'react', 'react-dom', '@primer/components', '@githubprimer/octicons-react', 'next/config', 'tree-model', 'path', 'react-measure', 'html-2-jsx', 'react-live', 'prism-github/prism-github.scss', 'prop-types', 'next/link', 'styled-components', 'next/router'], factory) : | ||
(factory((global.primer = {}),global.React,global.ReactDOM,global.components,global.Octicon,global.getConfig,global.TreeModel,global.path,global.Measure,global.HTMLtoJSX,global.reactLive,null,global.propTypes,global.NextLink,global.styled,global.router)); | ||
}(this, (function (exports,React,ReactDOM,components,Octicon,getConfig,TreeModel,path,Measure,HTMLtoJSX,reactLive,prismGithub_scss,propTypes,NextLink,styled,router) { 'use strict'; | ||
@@ -413,2 +413,29 @@ var React__default = 'default' in React ? React['default'] : React; | ||
function sortCompare(a, b, get) { | ||
var aa = get(a); | ||
var bb = get(b); | ||
return typeof aa === 'string' && typeof bb === 'string' ? aa.localeCompare(bb) : undefined; | ||
} | ||
function nodeSort(a, b) { | ||
return sortCompare(a, b, function (node) { | ||
return node.meta.sort_title || node.meta.title; | ||
}); | ||
} | ||
function addPath(el, path$$1) { | ||
// if there's no path, just return the element | ||
if (!path$$1) return el; // if this is a link it'll have an "href"; otherwise, add "path" | ||
var prop = el.props.href ? 'href' : 'path'; | ||
var value = el.props[prop]; | ||
var props = {}; // if there's a value and it's not absolute, prefix it with the path | ||
if (value && !value.match(/^(\/|https?:)/)) { | ||
props[prop] = path.join(path$$1, value); | ||
} else { | ||
props[prop] = path$$1; | ||
} | ||
return React__default.cloneElement(el, props); | ||
} | ||
var Frame = | ||
@@ -784,3 +811,3 @@ /*#__PURE__*/ | ||
/** | ||
* The NodeLink component takes an `href` and optional `children`. | ||
* The PageLink component takes an `href` and optional `children`. | ||
* If no `children` are provided, we look up the "node" of the corresponding | ||
@@ -797,11 +824,11 @@ * page in the tree (the one whose `path` matches the given `href`) and use | ||
* | ||
* The following instance of NodeLink should render a link to "/foo/bar" with | ||
* The following instance of PageLink should render a link to "/foo/bar" with | ||
* "Foo Bar" as its text: | ||
* | ||
* ```jsx | ||
* <NodeLink href="/foo/bar" /> | ||
* <PageLink href="/foo/bar" /> | ||
* ``` | ||
*/ | ||
function NodeLink(props) { | ||
function PageLink(props) { | ||
var href = props.href, | ||
@@ -820,19 +847,92 @@ content = props.children; | ||
} | ||
NodeLink.displayName = "NodeLink"; | ||
PageLink.displayName = "PageLink"; | ||
var NavLink = router.withRouter(function (_ref) { | ||
var _ref$is = _ref.is, | ||
Tag = _ref$is === void 0 ? NodeLink : _ref$is, | ||
href = _ref.href, | ||
var href = _ref.href, | ||
router$$1 = _ref.router, | ||
rest = _objectWithoutProperties(_ref, ["is", "href", "router"]); | ||
rest = _objectWithoutProperties(_ref, ["href", "router"]); | ||
return React__default.createElement(Tag, _extends({ | ||
return React__default.createElement(components.Box, rest, React__default.createElement(PageLink, _extends({ | ||
href: href, | ||
color: "white", | ||
px: 4, | ||
fontWeight: router$$1.pathname === href ? 'bold' : null | ||
}, rest)); | ||
color: router$$1.pathname === href ? 'black' : undefined, | ||
fontSize: 1 | ||
}, rest))); | ||
}); | ||
/** | ||
* A <Section> gets a `path` and optional children. If it has children it will | ||
* render those and prepend each child's `href` prop with the provided `path`. | ||
* This means that you can do: | ||
* | ||
* ```jsx | ||
* <Section path="/section"> | ||
* <Link href="foo">Links to /section/foo</Link> | ||
* </Section> | ||
* ``` | ||
* | ||
* If no children are provided, it renders a <NavList> with the provided | ||
* `path`. | ||
*/ | ||
var Section = function Section(_ref) { | ||
var path$$1 = _ref.path, | ||
children = _ref.children; | ||
return React__default.createElement(components.BorderBox, { | ||
p: 5, | ||
border: 0, | ||
borderBottom: 1, | ||
borderRadius: 0, | ||
width: "100%" | ||
}, children && path$$1 ? React__default.Children.map(children, function (child) { | ||
return addPath(child, path$$1); | ||
}) : React__default.createElement(NavList, { | ||
path: path$$1 | ||
})); | ||
}; | ||
Section.displayName = "Section"; | ||
/** | ||
* A <Section.Link> is really just a <PageLink> that's bold when its `href` | ||
* matches the current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
var SectionLink = router.withRouter(function (_ref2) { | ||
var href = _ref2.href, | ||
router$$1 = _ref2.router, | ||
rest = _objectWithoutProperties(_ref2, ["href", "router"]); | ||
return React__default.createElement(components.Box, rest, React__default.createElement(PageLink, _extends({ | ||
href: href | ||
}, rest, { | ||
fontSize: 2, | ||
fontWeight: router$$1.pathname.startsWith(href) ? 'bold' : null | ||
}))); | ||
}); | ||
Section.Link = SectionLink; | ||
/** | ||
* A <NavList> renders a <Section.Link> for the given `path` and looks up the | ||
* path in the page tree. If a node is found, it renders a <NavLink> for each | ||
* of the node's children. | ||
*/ | ||
function NavList(_ref) { | ||
var path$$1 = _ref.path; | ||
var node = rootPage.first(function (node) { | ||
return node.path === path$$1; | ||
}); | ||
var children = node ? node.children.sort(nodeSort) : []; | ||
return React__default.createElement(React__default.Fragment, null, React__default.createElement(Section.Link, { | ||
color: "gray.9", | ||
href: path$$1, | ||
mb: 3 | ||
}), children.map(function (child) { | ||
return React__default.createElement(NavLink, { | ||
mt: 2, | ||
href: child.path, | ||
key: child.path | ||
}); | ||
})); | ||
} | ||
function Outline(_ref) { | ||
@@ -975,108 +1075,24 @@ var outline = _ref.outline, | ||
function SideNav(props) { | ||
return React__default.createElement(components.Relative, { | ||
is: "nav" | ||
}, React__default.createElement(components.Box, _extends({ | ||
id: "sidenav" | ||
}, props), React__default.createElement(components.Flex, { | ||
flexDirection: "column", | ||
alignItems: "start" | ||
}, React__default.createElement(Router, null, React__default.createElement(RouteMatch, { | ||
path: "/blueprints" | ||
}, React__default.createElement(Section, { | ||
path: "components" | ||
})))))); | ||
} | ||
SideNav.displayName = "SideNav"; | ||
/** | ||
* A <Section> gets a `path` and optional children. If it has children it will | ||
* render those and prepend each child's `href` prop with the provided `path`. | ||
* This means that you can do: | ||
* <RouteMatch> is just a way to conditionally render content without a wrapper | ||
* element when contained directly in a <Router>: | ||
* | ||
* ```jsx | ||
* <Section path="/section"> | ||
* <Link href="foo">Links to /section/foo</Link> | ||
* </Section> | ||
* <Router> | ||
* <RouteMatch path="/some/dir"> | ||
* this will only show up on pages whose path begins with "/some/dir" | ||
* </RouteMatch> | ||
* </Router> | ||
* ``` | ||
* | ||
* If no children are provided, it renders a <NavList> with the provided | ||
* `path`. | ||
*/ | ||
var Section = function Section(_ref) { | ||
function RouteMatch(_ref) { | ||
var path$$1 = _ref.path, | ||
children = _ref.children; | ||
return React__default.createElement(components.BorderBox, { | ||
p: 5, | ||
border: 0, | ||
borderBottom: 1, | ||
borderRadius: 0, | ||
width: "100%" | ||
}, children && path$$1 ? React__default.Children.map(children, function (child) { | ||
return path$$1 ? React__default.Children.map(children, function (child) { | ||
return addPath(child, path$$1); | ||
}) : React__default.createElement(NavList, { | ||
path: path$$1 | ||
})); | ||
}; | ||
Section.displayName = "Section"; | ||
/** | ||
* A <NavList> renders a <SectionLink> for the given `path` and looks up the | ||
* path in the page tree. If a node is found, it renders a <NavLink> for each | ||
* of the node's children. | ||
*/ | ||
function NavList(_ref2) { | ||
var path$$1 = _ref2.path; | ||
var node = rootPage.first(function (node) { | ||
return node.path === path$$1; | ||
}); | ||
var children = node ? node.children.sort(nodeSort) : []; | ||
return React__default.createElement(React__default.Fragment, null, React__default.createElement(SectionLink, { | ||
href: path$$1, | ||
mb: 3 | ||
}), children.map(function (child) { | ||
return React__default.createElement(NavLink$1, { | ||
href: child.path, | ||
key: child.path | ||
}); | ||
})); | ||
}) : children; | ||
} | ||
/** | ||
* A <SectionLink> is really just a <NodeLink> that's bold when its `href` | ||
* matches the current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
var SectionLink = router.withRouter(function (_ref3) { | ||
var href = _ref3.href, | ||
router$$1 = _ref3.router, | ||
rest = _objectWithoutProperties(_ref3, ["href", "router"]); | ||
return React__default.createElement(components.Box, rest, React__default.createElement(NodeLink, { | ||
href: href, | ||
color: "gray.9", | ||
fontSize: 2, | ||
fontWeight: router$$1.pathname.startsWith(href) ? 'bold' : null | ||
})); | ||
}); | ||
/** | ||
* A <NavLink> is a <NodeLink> that turns black when its `href` matches the | ||
* current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
var NavLink$1 = router.withRouter(function (_ref4) { | ||
var href = _ref4.href, | ||
router$$1 = _ref4.router, | ||
rest = _objectWithoutProperties(_ref4, ["href", "router"]); | ||
return React__default.createElement(components.Box, { | ||
mt: 2 | ||
}, React__default.createElement(NodeLink, _extends({ | ||
href: href, | ||
color: router$$1.pathname === href ? 'black' : undefined, | ||
fontSize: 1 | ||
}, rest))); | ||
}); | ||
/** | ||
* This is inspired by React Router's <Router> component, in that it looks for | ||
@@ -1088,5 +1104,5 @@ * children with the `path` prop and only renders the _first_ one that matches | ||
var Router = router.withRouter(function (_ref5) { | ||
var router$$1 = _ref5.router, | ||
children = _ref5.children; | ||
var Router = router.withRouter(function (_ref) { | ||
var router$$1 = _ref.router, | ||
children = _ref.children; | ||
var matched = false; | ||
@@ -1103,52 +1119,16 @@ return React__default.Children.toArray(children).map(function (child) { | ||
}); | ||
/** | ||
* <RouteMatch> is just a way to conditionally render content without a wrapper | ||
* element when contained directly in a <Router>: | ||
* | ||
* ```jsx | ||
* <Router> | ||
* <RouteMatch path="/some/dir"> | ||
* this will only show up on pages whose path begins with "/some/dir" | ||
* </RouteMatch> | ||
* </Router> | ||
* ``` | ||
*/ | ||
function RouteMatch(_ref6) { | ||
var path$$1 = _ref6.path, | ||
children = _ref6.children; | ||
return path$$1 ? React__default.Children.map(children, function (child) { | ||
return addPath(child, path$$1); | ||
}) : children; | ||
function SideNav(props) { | ||
return React__default.createElement(components.Relative, { | ||
is: "nav" | ||
}, React__default.createElement(components.Box, _extends({ | ||
id: "sidenav" | ||
}, props), React__default.createElement(components.Flex, { | ||
flexDirection: "column", | ||
alignItems: "start" | ||
}, React__default.createElement(Router, null, props.children)))); | ||
} | ||
function sortCompare(a, b, get) { | ||
var aa = get(a); | ||
var bb = get(b); | ||
return typeof aa === 'string' && typeof bb === 'string' ? aa.localeCompare(bb) : undefined; | ||
} | ||
SideNav.displayName = "SideNav"; | ||
function nodeSort(a, b) { | ||
return sortCompare(a, b, function (node) { | ||
return node.meta.sort_title || node.meta.title; | ||
}); | ||
} | ||
function addPath(el, path$$1) { | ||
// if there's no path, just return the element | ||
if (!path$$1) return el; // if this is a link it'll have an "href"; otherwise, add "path" | ||
var prop = el.props.href ? 'href' : 'path'; | ||
var value = el.props[prop]; | ||
var props = {}; // if there's a value and it's not absolute, prefix it with the path | ||
if (value && !value.match(/^(\/|https?:)/)) { | ||
props[prop] = path.join(path$$1, value); | ||
} else { | ||
props[prop] = path$$1; | ||
} | ||
return React__default.cloneElement(el, props); | ||
} | ||
exports.ClipboardCopy = ClipboardCopy; | ||
@@ -1161,5 +1141,9 @@ exports.CodeExample = CodeExample; | ||
exports.NavLink = NavLink; | ||
exports.NodeLink = NodeLink; | ||
exports.NavList = NavList; | ||
exports.Outline = Outline; | ||
exports.PackageHeader = PackageHeader; | ||
exports.PageLink = PageLink; | ||
exports.RouteMatch = RouteMatch; | ||
exports.Router = Router; | ||
exports.Section = Section; | ||
exports.SideNav = SideNav; | ||
@@ -1177,2 +1161,5 @@ exports.StatusLabel = StatusLabel; | ||
exports.rootPage = rootPage; | ||
exports.sortCompare = sortCompare; | ||
exports.nodeSort = nodeSort; | ||
exports.addPath = addPath; | ||
@@ -1179,0 +1166,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
{ | ||
"name": "@primer/blueprints", | ||
"version": "0.0.0-d9dc9d0", | ||
"version": "0.0.0-ec20941", | ||
"description": "Components for GitHub Documentation Sites", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.umd.js", |
@@ -8,6 +8,10 @@ export {default as ClipboardCopy} from './ClipboardCopy' | ||
export {default as NavLink} from './NavLink' | ||
export {default as NodeLink} from './NodeLink' | ||
export {default as NavList} from './NavList' | ||
export {default as Outline} from './Outline' | ||
export {default as PackageHeader} from './PackageHeader' | ||
export {default as PageLink} from './PageLink' | ||
export {default as RouteMatch} from './RouteMatch' | ||
export {default as Router} from './Router' | ||
export {default as Section} from './Section' | ||
export {default as SideNav} from './SideNav' | ||
export {default as StatusLabel} from './StatusLabel' |
import React from 'react' | ||
import {withRouter} from 'next/router' | ||
import NodeLink from './NodeLink' | ||
import {Box} from '@primer/components' | ||
import PageLink from './PageLink' | ||
export default withRouter(({is: Tag = NodeLink, href, router, ...rest}) => ( | ||
<Tag href={href} color="white" px={4} fontWeight={router.pathname === href ? 'bold' : null} {...rest} /> | ||
)) | ||
const NavLink = withRouter(({href, router, ...rest}) => { | ||
return ( | ||
<Box {...rest}> | ||
<PageLink href={href} color={router.pathname === href ? 'black' : undefined} fontSize={1} {...rest} /> | ||
</Box> | ||
) | ||
}) | ||
export default NavLink |
import React from 'react' | ||
import {join} from 'path' | ||
import {withRouter} from 'next/router' | ||
import {Box, BorderBox, Flex, Relative} from '@primer/components' | ||
import NodeLink from './NodeLink' | ||
import {rootPage} from './utils' | ||
import {Box, Flex, Relative} from '@primer/components' | ||
import Router from './Router' | ||
export default function SideNav(props) { | ||
function SideNav(props) { | ||
return ( | ||
@@ -13,7 +10,3 @@ <Relative is="nav"> | ||
<Flex flexDirection="column" alignItems="start"> | ||
<Router> | ||
<RouteMatch path="/blueprints"> | ||
<Section path="components" /> | ||
</RouteMatch> | ||
</Router> | ||
<Router>{props.children}</Router> | ||
</Flex> | ||
@@ -25,122 +18,2 @@ </Box> | ||
/** | ||
* A <Section> gets a `path` and optional children. If it has children it will | ||
* render those and prepend each child's `href` prop with the provided `path`. | ||
* This means that you can do: | ||
* | ||
* ```jsx | ||
* <Section path="/section"> | ||
* <Link href="foo">Links to /section/foo</Link> | ||
* </Section> | ||
* ``` | ||
* | ||
* If no children are provided, it renders a <NavList> with the provided | ||
* `path`. | ||
*/ | ||
const Section = ({path, children}) => ( | ||
<BorderBox p={5} border={0} borderBottom={1} borderRadius={0} width="100%"> | ||
{children && path ? React.Children.map(children, child => addPath(child, path)) : <NavList path={path} />} | ||
</BorderBox> | ||
) | ||
/** | ||
* A <NavList> renders a <SectionLink> for the given `path` and looks up the | ||
* path in the page tree. If a node is found, it renders a <NavLink> for each | ||
* of the node's children. | ||
*/ | ||
function NavList({path}) { | ||
const node = rootPage.first(node => node.path === path) | ||
const children = node ? node.children.sort(nodeSort) : [] | ||
return ( | ||
<> | ||
<SectionLink href={path} mb={3} /> | ||
{children.map(child => ( | ||
<NavLink href={child.path} key={child.path} /> | ||
))} | ||
</> | ||
) | ||
} | ||
/** | ||
* A <SectionLink> is really just a <NodeLink> that's bold when its `href` | ||
* matches the current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
const SectionLink = withRouter(({href, router, ...rest}) => ( | ||
<Box {...rest}> | ||
<NodeLink href={href} color="gray.9" fontSize={2} fontWeight={router.pathname.startsWith(href) ? 'bold' : null} /> | ||
</Box> | ||
)) | ||
/** | ||
* A <NavLink> is a <NodeLink> that turns black when its `href` matches the | ||
* current path, wrapped in a <Box> for whitespace. | ||
*/ | ||
const NavLink = withRouter(({href, router, ...rest}) => { | ||
return ( | ||
<Box mt={2}> | ||
<NodeLink href={href} color={router.pathname === href ? 'black' : undefined} fontSize={1} {...rest} /> | ||
</Box> | ||
) | ||
}) | ||
/** | ||
* This is inspired by React Router's <Router> component, in that it looks for | ||
* children with the `path` prop and only renders the _first_ one that matches | ||
* the beginning of the current path. Children without a `path` prop are always | ||
* rendered. | ||
*/ | ||
const Router = withRouter(({router, children}) => { | ||
let matched = false | ||
return React.Children.toArray(children).map(child => { | ||
if (child.props.path) { | ||
if (!matched && router.pathname.indexOf(child.props.path) === 0) { | ||
return (matched = child) | ||
} | ||
} else { | ||
return child | ||
} | ||
}) | ||
}) | ||
/** | ||
* <RouteMatch> is just a way to conditionally render content without a wrapper | ||
* element when contained directly in a <Router>: | ||
* | ||
* ```jsx | ||
* <Router> | ||
* <RouteMatch path="/some/dir"> | ||
* this will only show up on pages whose path begins with "/some/dir" | ||
* </RouteMatch> | ||
* </Router> | ||
* ``` | ||
*/ | ||
function RouteMatch({path, children}) { | ||
return path ? React.Children.map(children, child => addPath(child, path)) : children | ||
} | ||
function sortCompare(a, b, get) { | ||
const aa = get(a) | ||
const bb = get(b) | ||
return typeof aa === 'string' && typeof bb === 'string' ? aa.localeCompare(bb) : undefined | ||
} | ||
function nodeSort(a, b) { | ||
return sortCompare(a, b, node => node.meta.sort_title || node.meta.title) | ||
} | ||
function addPath(el, path) { | ||
// if there's no path, just return the element | ||
if (!path) return el | ||
// if this is a link it'll have an "href"; otherwise, add "path" | ||
const prop = el.props.href ? 'href' : 'path' | ||
const value = el.props[prop] | ||
const props = {} | ||
// if there's a value and it's not absolute, prefix it with the path | ||
if (value && !value.match(/^(\/|https?:)/)) { | ||
props[prop] = join(path, value) | ||
} else { | ||
props[prop] = path | ||
} | ||
return React.cloneElement(el, props) | ||
} | ||
export default SideNav |
import React from 'react' | ||
import getConfig from 'next/config' | ||
import TreeModel from 'tree-model' | ||
import {join} from 'path' | ||
@@ -88,1 +89,28 @@ export const CommonStyles = () => { | ||
} | ||
export function sortCompare(a, b, get) { | ||
const aa = get(a) | ||
const bb = get(b) | ||
return typeof aa === 'string' && typeof bb === 'string' ? aa.localeCompare(bb) : undefined | ||
} | ||
export function nodeSort(a, b) { | ||
return sortCompare(a, b, node => node.meta.sort_title || node.meta.title) | ||
} | ||
export function addPath(el, path) { | ||
// if there's no path, just return the element | ||
if (!path) return el | ||
// if this is a link it'll have an "href"; otherwise, add "path" | ||
const prop = el.props.href ? 'href' : 'path' | ||
const value = el.props[prop] | ||
const props = {} | ||
// if there's a value and it's not absolute, prefix it with the path | ||
if (value && !value.match(/^(\/|https?:)/)) { | ||
props[prop] = join(path, value) | ||
} else { | ||
props[prop] = path | ||
} | ||
return React.cloneElement(el, props) | ||
} |
26
95436
2771