@primer/blueprints
Advanced tools
Comparing version 0.0.0-16066f1 to 0.0.0-190a0c6
import React, { useEffect, useState } from 'react'; | ||
import ReactDOM, { findDOMNode } from 'react-dom'; | ||
import { Button, BorderBox, Absolute, Box, StyledOcticon, Relative, Text, Link, Avatar, Flex, Sticky } from '@primer/components'; | ||
import Octicon, { Clippy, getIconByName, MarkGithub, PrimitiveDot, Comment, Info, FileCode, Alert } from '@githubprimer/octicons-react'; | ||
import { Button, BorderBox, Absolute, Box, StyledOcticon, Relative, Text, Link, Avatar, Flex, theme, TextInput, Sticky, Heading } from '@primer/components'; | ||
import Octicon, { Clippy, getIconByName, ChevronDown, MarkGithub, ChevronRight, Link as Link$1, PrimitiveDot, Comment, Info, FileCode, Alert } from '@githubprimer/octicons-react'; | ||
import getConfig from 'next/config'; | ||
import TreeModel from 'tree-model'; | ||
import { join } from 'path'; | ||
import Measure from 'react-measure'; | ||
@@ -11,7 +12,10 @@ import HTMLtoJSX from 'html-2-jsx'; | ||
import 'prism-github/prism-github.scss'; | ||
import 'prop-types'; | ||
import PropTypes from 'prop-types'; | ||
import styled from 'styled-components'; | ||
import { space, color, themeGet, get } from 'styled-system'; | ||
import NextLink from 'next/link'; | ||
import styled from 'styled-components'; | ||
import { withRouter } from 'next/router'; | ||
import { join } from 'path'; | ||
import lunr from 'lunr'; | ||
import Downshift from 'downshift'; | ||
import classnames from 'classnames'; | ||
@@ -73,2 +77,21 @@ function _classCallCheck(instance, Constructor) { | ||
function _objectSpread(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
var ownKeys = Object.keys(source); | ||
if (typeof Object.getOwnPropertySymbols === 'function') { | ||
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(source, sym).enumerable; | ||
})); | ||
} | ||
ownKeys.forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} | ||
return target; | ||
} | ||
function _inherits(subClass, superClass) { | ||
@@ -414,2 +437,29 @@ if (typeof superClass !== "function" && superClass !== null) { | ||
function sortCompare(a, b, get$$1) { | ||
var aa = get$$1(a); | ||
var bb = get$$1(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 = | ||
@@ -702,3 +752,88 @@ /*#__PURE__*/ | ||
function Link$1(_ref) { | ||
function _templateObject2() { | ||
var data = _taggedTemplateLiteral(["\n ", ";\n ", ";\n"]); | ||
_templateObject2 = function _templateObject2() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject() { | ||
var data = _taggedTemplateLiteral(["\n & > summary {\n list-style: none;\n }\n & > summary::-webkit-details-marker {\n display: none;\n }\n"]); | ||
_templateObject = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var DetailsReset = styled('details')(_templateObject()); | ||
function getRenderer(children) { | ||
return typeof children === 'function' ? children : function () { | ||
return children; | ||
}; | ||
} | ||
function DetailsBase(_ref) { | ||
var children = _ref.children, | ||
overlay = _ref.overlay, | ||
_ref$render = _ref.render, | ||
render = _ref$render === void 0 ? getRenderer(children) : _ref$render, | ||
rest = _objectWithoutProperties(_ref, ["children", "overlay", "render"]); | ||
var _useState = useState(Boolean(rest.open)), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
open = _useState2[0], | ||
setOpen = _useState2[1]; | ||
function toggle(event) { | ||
if (event) event.preventDefault(); | ||
if (overlay) { | ||
openMenu(); | ||
} else { | ||
setOpen(!open); | ||
} | ||
} | ||
function openMenu() { | ||
if (!open) { | ||
setOpen(true); | ||
document.addEventListener('click', closeMenu); | ||
} | ||
} | ||
function closeMenu() { | ||
setOpen(false); | ||
document.removeEventListener('click', closeMenu); | ||
} | ||
return React.createElement(DetailsReset, _extends({}, rest, { | ||
open: open, | ||
overlay: overlay | ||
}), render({ | ||
open: open, | ||
toggle: toggle | ||
})); | ||
} | ||
DetailsBase.displayName = "DetailsBase"; | ||
var Details = styled(DetailsBase)(_templateObject2(), space, color); | ||
Details.defaultProps = { | ||
theme: theme, | ||
overlay: false | ||
}; | ||
Details.propTypes = { | ||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | ||
className: PropTypes.string, | ||
open: PropTypes.bool, | ||
overlay: PropTypes.bool, | ||
render: PropTypes.func, | ||
theme: PropTypes.object | ||
}; | ||
function Link$2(_ref) { | ||
var href = _ref.href, | ||
@@ -713,8 +848,283 @@ rest = _objectWithoutProperties(_ref, ["href"]); | ||
} | ||
Link$1.displayName = "Link"; | ||
Link$2.displayName = "Link"; | ||
function _templateObject() { | ||
var get$1 = function get$$1(key) { | ||
return themeGet(key, get(theme, key)); | ||
}; | ||
var getDirectionStyles = function getDirectionStyles(theme$$1, direction) { | ||
var map = { | ||
w: "\n top: 0;\n right: 100%;\n left: auto;\n width: auto;\n margin-top: 0;\n margin-right: 10px;\n\n &::before {\n top: 10px;\n right: -16px;\n left: auto;\n border-color: transparent;\n border-left-color: ".concat(get$1('colors.blackfade15')(theme$$1), ";\n }\n\n &::after {\n top: 11px;\n right: -14px;\n left: auto;\n border-color: transparent;\n border-left-color: ").concat(get$1('colors.white')(theme$$1), ";\n }\n "), | ||
e: "\n top: 0;\n left: 100%;\n width: auto;\n margin-top: 0;\n margin-left: 10px;\n\n &::before {\n top: 10px;\n left: -16px;\n border-color: transparent;\n border-right-color: ".concat(get$1('colors.blackfade15')(theme$$1), ";\n }\n\n &::after {\n top: 11px;\n left: -14px;\n border-color: transparent;\n border-right-color: ").concat(get$1('colors.white')(theme$$1), ";\n }\n "), | ||
ne: "\n top: auto;\n bottom: 100%;\n left: 0;\n margin-bottom: 3px;\n\n &::before,\n &::after {\n top: auto;\n right: auto;\n }\n\n &::before {\n bottom: -8px;\n left: 9px;\n border-top: 8px solid ".concat(get$1('colors.blackfade15')(theme$$1), ";\n border-bottom: 0;\n border-left: 8px solid transparent;\n }\n\n &::after {\n bottom: -7px;\n left: 10px;\n border-top: 7px solid ").concat(get$1('colors.white')(theme$$1), ";\n border-right: 7px solid transparent;\n border-bottom: 0;\n border-left: 7px solid transparent;\n }\n "), | ||
s: "\n right: 50%;\n left: auto;\n transform: translateX(50%);\n\n &::before {\n top: -16px;\n right: 50%;\n transform: translateX(50%);\n }\n\n &::after {\n top: -14px;\n right: 50%;\n transform: translateX(50%);\n }\n ", | ||
sw: "\n right: 0;\n left: auto;\n\n &::before {\n top: -16px;\n right: 9px;\n left: auto;\n }\n\n &::after {\n top: -14px;\n right: 10px;\n left: auto;\n }\n ", | ||
se: "\n &::before {\n top: -16px;\n left: 9px;\n }\n\n &::after {\n top: -14px;\n left: 10px;\n }\n " | ||
}; | ||
return map[direction]; | ||
}; | ||
function _templateObject$1() { | ||
var data = _taggedTemplateLiteral(["\n color: ", ";\n display: block;\n padding: 0 ", "px;\n line-height: 30px;\n white-space: nowrap;\n &:hover {\n color: ", ";\n background-color: ", ";\n text-decoration: none;\n }\n &:last-child:hover {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n }\n &:first-child:hover {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n }\n"]); | ||
_templateObject$1 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var NavItem = styled(Link)(_templateObject$1(), theme.colors.blue[2], theme.space[3], theme.colors.black, theme.colors.blue[4]); | ||
function _templateObject$2() { | ||
var data = _taggedTemplateLiteral(["\n box-shadow: 0px 4px 12px rgba(27, 31, 35, 0.15);\n border: 1px solid rgba(219, 237, 255, 0.3);\n border-radius: 4px;\n ", ";\n"]); | ||
_templateObject$2 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var DropdownMenu = styled.div(_templateObject$2(), function (props) { | ||
return props.direction ? getDirectionStyles(props.theme, props.direction) : ''; | ||
}); | ||
function NavDropdown(_ref) { | ||
var children = _ref.children, | ||
title = _ref.title, | ||
_ref$direction = _ref.direction, | ||
direction = _ref$direction === void 0 ? 'se' : _ref$direction; | ||
return React.createElement(Box, null, React.createElement(Details, { | ||
overlay: true, | ||
mx: 3, | ||
render: function render(_ref2) { | ||
var toggle = _ref2.toggle; | ||
return React.createElement(React.Fragment, null, React.createElement(Text, { | ||
fontWeight: "bold", | ||
color: "blue.2", | ||
is: "summary", | ||
onClick: toggle | ||
}, title, " ", React.createElement(StyledOcticon, { | ||
icon: ChevronDown | ||
})), React.createElement(Relative, null, React.createElement(DropdownMenu, { | ||
as: Absolute, | ||
zIndex: 90, | ||
bg: "black", | ||
direction: direction | ||
}, children))); | ||
} | ||
})); | ||
} | ||
NavDropdown.displayName = "NavDropdown"; | ||
var documents = { | ||
"undefined": { | ||
"content": "import {Box, Heading} from '@primer/components'\nimport {CONTENT_MAX_WIDTH} from '../../src/constants'\n\nexport const Hero = () => (\n <Box bg=\"black\">\n <Box maxWidth={CONTENT_MAX_WIDTH} p={6} mx=\"auto\" mb={3}>\n <Box mt={4} mb={4}>\n <Heading fontWeight=\"bold\" color=\"blue.4\" fontSize={7} pb={3} m={0}>\n Primer Blueprints\n </Heading>\n </Box>\n </Box>\n </Box>\n)\n\n# Introduction\n\nThese components are to be used to build documentation sites across our different Primer projects.\n" | ||
}, | ||
"content-components/clipboard-copy": { | ||
"title": "ClipboardCopy", | ||
"path": "content-components/clipboard-copy", | ||
"content": "\nUse the ClipboardCopy component to add copying functionality next to code blocks in documentation.\nThe `value` prop must be provided with the current value of the code block.\n\n```.jsx\n<ClipboardCopy value={'hihihi'}/>\n\n```\n\n\n## Component props\n\n| Name | Type | Default | Description |\n| :- | :- | :-: | :- |\n| value | String | | The content that will be added to the user's clipboard when clicked.\n" | ||
}, | ||
"content-components/contributors": { | ||
"title": "Contributors", | ||
"path": "content-components/contributors", | ||
"content": "\nUse the Contributors component to add contributor credit to the bottom of any docs page. With a provided file path & repo path, the component will fetch commit data from the GitHub API and display all contributors to that file. In instances where you'd like to add additional contributor credits that are not reflected in the commit data (for example, if a repository has been moved and the git history lost) you can use the `contributor` prop to add additional contributors.\n\n\n```.jsx\n<Contributors\n filePath='README.md'\n repoPath='primer/components'\n contributors={[{login: 'emplums'}, {login: 'broccolini'}]}\n/>\n```\n\n## Component props\n\n| Name | Type | Default | Description |\n| :- | :- | :-: | :- |\n| filePath | String | | The path to the file you'd like to pull contributor data from. |\n| repoPath | String | | The repository path on GitHub. For example: `primer/components` |\n| contributors | Array | | Prop for adding additional contributors not reflected in commit history. Format is an array of objects with a `login` key. Ex. `[{login: 'emplums'}, {login: 'broccolini'}]` |\n" | ||
}, | ||
"content-components/code-example": { | ||
"title": "CodeExample", | ||
"path": "content-components/code-example", | ||
"content": "\nUse the CodeExample component to wrap HTML code examples. This component was created to prevent CSS from our markdown styles from bleeding over into examples by displaying examples in an iframe.\n\nThis component can also be passed to the component prop of your MDXProvider to replace all code blocks with CodeExample like so:\n\n```\nconst components = {\n code: CodeExample\n}\n\nreturn (\n <MDXProvider components={components}>\n <Component {...page} />\n </MDXProvider>\n)\n\n```\n\n```.jsx\n<CodeExample>\n <div>hello world!</div>\n</CodeExample>\n\n```\n" | ||
}, | ||
"content-components/frame": { | ||
"title": "Frame", | ||
"path": "content-components/frame", | ||
"content": "\nThe Frame component wraps children components in an iframe\n\n\n```.jsx\n<Frame minHeight={50}>\n <Text>Hi</Text>\n</Frame>\n```\n\n## Component props\n\n| Name | Type | Default | Description |\n| :- | :- | :-: | :- |\n| minHeight | String or Number | 0 | minHeight of iframe\n| border | String | 0 | border for element\n| borderRadius | String or Number | 0 | borderRadius for element\n| width | String or Number | 100% | width of iframe\n" | ||
}, | ||
"content-components/link": { | ||
"title": "Link", | ||
"path": "content-components/link", | ||
"content": "\nUse the Link component to add links within documentation. The link component wraps the standard Primer link with Next's link component for easy routing in Next.js applications.\n\n```.jsx\n<Link href=\"https://github.com/primer\">Primer</Link>\n\n```\n" | ||
}, | ||
"content-components/index": { | ||
"title": "Content Components", | ||
"path": "content-components/index", | ||
"content": "\n Components are reusable React components that can be used to build UI for our documentation sites.\n" | ||
}, | ||
"navigation-components/index": { | ||
"title": "Navigation Components", | ||
"path": "navigation-components/index", | ||
"content": "\nNavigation components can be used to build navigation on documentation sites\n" | ||
}, | ||
"navigation-components/header": { | ||
"title": "Header", | ||
"path": "navigation-components/header", | ||
"keywords": ["navigation", "header"], | ||
"content": "\nUse Header to provide a top navigation for your site. Children of `Header` will be rendered on the right side of the component. Children should be top level navigation links. The `title` prop specifies what should be rendered to the right of the GitHub Mark. The `root` prop specifies where you'd like the GitHub Mark to link to. Leave blank if you'd like it to route to `/`.\n```.jsx\n<Header title=\"Hello world!\" root='/blueprints'>\n <NavDropdown title={`What's new`}>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Design'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Development'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Content'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Tools'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n</Header>\n```\n" | ||
}, | ||
"navigation-components/nav-link": { | ||
"title": "NavLink", | ||
"path": "navigation-components/nav-link", | ||
"content": "\nThe NavLink component is a PageLink that turns black when it's href matches the current path. NavLinks are typically used in sidebar sub-navigation.\n\n\n```.jsx\nMatches current path:\n<NavLink mb={4} href='/blueprints/navigation-components/NavLink' />\n\nDoes not match current path:\n<NavLink href='/blueprints/navigation-components/Section' />\n```\n" | ||
}, | ||
"navigation-components/nav-list": { | ||
"title": "NavList", | ||
"path": "navigation-components/nav-list", | ||
"content": "\n\nA `<NavList>` renders a `<Section.Link>` for the given `path` and looks up the\npath in the page tree. If a node is found, it renders a `<NavLink>` for each\nof the node's children.\n\nThe automatically generated page links in a NavList are sorted alphabetically by either the sort_title or title frontmatter keys. If a page has a non-empty sort_title, that value is used only to determine its position in the list; otherwise, the title determines their sort order. The title key is always used as a page's link text.\n\n\n```.jsx\n<NavList path='/blueprints/content-components'/>\n```\n" | ||
}, | ||
"navigation-components/page-link": { | ||
"title": "PageLink", | ||
"path": "navigation-components/page-link", | ||
"content": "\nThe PageLink component takes an `href` and optional `children`.\nIf no `children` are provided, we look up the \"node\" of the corresponding\npage in the tree (the one whose `path` matches the given `href`) and use\nthat node's `title` frontmatter key. In other words, given the following\npages/foo/bar.md:\n\n```md\n---\ntitle: Foo Bar\n---\n```\n\nThe following instance of PageLink should render a link to \"/foo/bar\" with\n\"Foo Bar\" as its text:\n```.jsx\n<PageLink href=\"/foo/bar\" />\n```\n" | ||
}, | ||
"navigation-components/section": { | ||
"title": "Section", | ||
"path": "navigation-components/section", | ||
"content": "\nA `Section` gets a `path` and optional children. If it has children it will\nrender those and prepend each child's `href` prop with the provided `path`.\nThis means that you can do:\n\n```.jsx\n<Section path=\"/section\">\n <Section.Link href=\"foo\">Links to /section/foo</Section.Link>\n</Section>\n```\n\nIf no children are provided, it renders a [`NavList`](/blueprints/nav-components/NavList) with the provided\n`path`.\n" | ||
}, | ||
"navigation-components/route-match": { | ||
"title": "RouteMatch", | ||
"path": "navigation-components/route-match", | ||
"content": "\nUse `RouteMatch` to conditionally render content without a wrapper\nelement when contained directly in a `Router`. `RouteMatch` is most commonly used to conditionally render a chunk of side navigation links.\n\n\n```.jsx\n<Router>\n <RouteMatch path=\"/blueprints/navigation-components\">\n <Box>this will only show up on pages whose path begins with \"/blueprints/navigation-components\"</Box>\n </RouteMatch>\n <RouteMatch path=\"/blueprints/content-components\">\n <Box>this will only show up on pages whose path begins with \"/blueprints/content-components\"</Box>\n </RouteMatch>\n</Router>\n\n```\n" | ||
}, | ||
"navigation-components/side-nav": { | ||
"title": "SideNav", | ||
"path": "navigation-components/side-nav", | ||
"content": "\n\nContainer component that takes children and nests them in a Router with layout styling. The `SideNav` of this site uses `Section` components to show both the Content Components and Navigation Components sections. See [the `Section` docs](/blueprints/navigation-components/section) for more details.\n\nYou may also use the `RouteMatch` components in your `SideNav` to conditionally show specific navigation links in the SideNav depending on where you are on the docs site. See [`RouteMatch` docs](/blueprints/navigation-components/section) for more details.\n\n\n```.jsx\n<SideNav>\n <RouteMatch path=\"/blueprints\">\n <Section path=\"content-components\" />\n </RouteMatch>\n</SideNav>\n```\n" | ||
}, | ||
"tools/index": { | ||
"title": "Tools", | ||
"path": "tools/index", | ||
"content": "\nComing soon\n" | ||
} | ||
}; | ||
function _templateObject$3() { | ||
var data = _taggedTemplateLiteral(["\n display: block;\n text-decoration: none;\n color: ", ";\n background-color: ", ";\n padding: 8px;\n"]); | ||
_templateObject$3 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var SearchItem = styled(Link$2)(_templateObject$3(), function (props) { | ||
return props.isHighlighted ? '#fff' : '#24292e'; | ||
}, function (props) { | ||
return props.isHighlighted ? '#0366d6' : '#fff'; | ||
}); | ||
function _templateObject$4() { | ||
var data = _taggedTemplateLiteral(["\n color: #fff;\n background-color: rgba(255, 255, 255, 0.07);\n border: 1px;\n border: 1px solid transparent;\n &:focus,\n &:active {\n border: 1px solid rgba(255, 255, 255, 0.15);\n outline: none;\n box-shadow: none;\n }\n"]); | ||
_templateObject$4 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var SearchInput = styled(TextInput)(_templateObject$4()); | ||
function _templateObject$5() { | ||
var data = _taggedTemplateLiteral(["\n box-shadow: 0 1px 5px rgba(27, 31, 35, 0.15);\n width: 100%;\n overflow: auto;\n right: 0;\n background-color: #fff;\n display: ", ";\n position: absolute;\n\n @media (min-width: 1012px) {\n width: 0;\n min-width: 320px;\n height: auto;\n max-height: 240px;\n border-radius: 3px;\n border: 1px solid #e1e4e8;\n padding-bottom: 0;\n }\n"]); | ||
_templateObject$5 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var SearchResults = styled.div(_templateObject$5(), function (props) { | ||
return props.open ? 'block' : 'none'; | ||
}); | ||
function Search(_ref) { | ||
var root = _ref.root; | ||
var idx = lunr(function () { | ||
this.ref('path'); //eslint-disable-line | ||
this.field('title'); //eslint-disable-line | ||
this.field('content'); //eslint-disable-line | ||
this.field('keywords'); //eslint-disable-line | ||
var _arr = Object.values(documents); | ||
for (var _i = 0; _i < _arr.length; _i++) { | ||
var doc = _arr[_i]; | ||
this.add(doc); //eslint-disable-line | ||
} | ||
}); | ||
var _useState = useState([]), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
results = _useState2[0], | ||
setResults = _useState2[1]; | ||
var onChange = function onChange(e) { | ||
if (e.target) { | ||
setResults(idx.search(e.target.value)); | ||
} | ||
}; | ||
var renderResults = function renderResults(selectedItem, getItemProps, highlightedIndex) { | ||
return results.map(function (result, index) { | ||
var doc = documents[result.ref]; | ||
return React.createElement(SearchItem //eslint-disable-line | ||
, getItemProps({ | ||
item: result, | ||
index: index, | ||
key: result.ref, | ||
href: "/".concat(root, "/").concat(doc.path), | ||
isHighlighted: highlightedIndex === index | ||
}), doc.title); | ||
}); | ||
}; | ||
function stateReducer(state, changes) { | ||
switch (changes.type) { | ||
case Downshift.stateChangeTypes.keyDownEnter: | ||
case Downshift.stateChangeTypes.clickItem: | ||
return _objectSpread({}, changes, { | ||
inputValue: '' | ||
}); | ||
default: | ||
return changes; | ||
} | ||
} | ||
return React.createElement(Box, { | ||
is: Relative | ||
}, React.createElement(Downshift, { | ||
onChange: onChange, | ||
itemToString: function itemToString(item) { | ||
return item ? documents[item.ref].title : ''; | ||
}, | ||
stateReducer: stateReducer | ||
}, function (_ref2) { | ||
var getInputProps = _ref2.getInputProps, | ||
getMenuProps = _ref2.getMenuProps, | ||
getLabelProps = _ref2.getLabelProps, | ||
getItemProps = _ref2.getItemProps, | ||
isOpen = _ref2.isOpen, | ||
highlightedIndex = _ref2.highlightedIndex, | ||
selectedItem = _ref2.selectedItem; | ||
return React.createElement("div", null, React.createElement("label", _extends({ | ||
hidden: true | ||
}, getLabelProps()), ' ', "//eslint-disable-line Search docs"), React.createElement(SearchInput, _extends({ | ||
placeholder: "Search" | ||
}, getInputProps({ | ||
onChange: onChange | ||
}))), React.createElement(SearchResults, _extends({ | ||
open: isOpen | ||
}, getMenuProps()), renderResults(selectedItem, getItemProps, highlightedIndex))); | ||
})); | ||
} | ||
Search.displayName = "Search"; | ||
function _templateObject$6() { | ||
var data = _taggedTemplateLiteral(["\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n"]); | ||
_templateObject = function _templateObject() { | ||
_templateObject$6 = function _templateObject() { | ||
return data; | ||
@@ -725,3 +1135,3 @@ }; | ||
} | ||
var BoxShadow = styled(Box)(_templateObject()); | ||
var BoxShadow = styled(Box)(_templateObject$6()); | ||
@@ -738,2 +1148,3 @@ var HeaderText = function HeaderText(props) { | ||
var title = _ref.title, | ||
subtitle = _ref.subtitle, | ||
root = _ref.root, | ||
@@ -751,19 +1162,32 @@ children = _ref.children; | ||
justifyContent: "space-between" | ||
}, React.createElement(Link$1, { | ||
href: "/".concat(root), | ||
color: "white", | ||
ml: 3 | ||
}, React.createElement(Flex, { | ||
alignItems: "center", | ||
justifyContent: "center" | ||
}, React.createElement(Octicon, { | ||
}, React.createElement(Link$2, { | ||
href: "https://primer.style/".concat(root), | ||
color: "white", | ||
mx: 3 | ||
}, React.createElement(Flex, { | ||
alignItems: "center" | ||
}, React.createElement(StyledOcticon, { | ||
color: "blue.4", | ||
icon: MarkGithub, | ||
size: "medium" | ||
}), React.createElement(HeaderText, { | ||
ml: 3 | ||
}, title))), React.createElement(Box, { | ||
display: ['none', 'none', 'block'] | ||
}, React.createElement(HeaderText, null, children)), React.createElement(Box, { | ||
ml: 3, | ||
color: "blue.4", | ||
fontFamily: "mono" | ||
}, title), React.createElement(StyledOcticon, { | ||
icon: ChevronRight, | ||
mx: 2, | ||
color: "blue.2" | ||
}), React.createElement(HeaderText, { | ||
fontWeight: "bold" | ||
}, subtitle))), React.createElement(Search, { | ||
root: root | ||
})), React.createElement(Box, { | ||
display: ['none', 'none', 'flex'] | ||
}, children), React.createElement(Box, { | ||
display: ['block', 'block', 'none'] | ||
}, React.createElement(Link$1, { | ||
}, React.createElement(Link$2, { | ||
href: "#sidenav" | ||
@@ -789,4 +1213,43 @@ }, React.createElement(BorderBox, { | ||
function _templateObject$7() { | ||
var data = _taggedTemplateLiteral(["\n .anchor {\n display: none;\n }\n &:hover .anchor {\n display: inline-block;\n }\n &:focus .anchor {\n display: inline-block;\n }\n"]); | ||
_templateObject$7 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var Anchor = function Anchor(_ref) { | ||
var id = _ref.id, | ||
className = _ref.className; | ||
return React.createElement("a", { | ||
href: "#".concat(id), | ||
className: classnames('anchor', className) | ||
}, React.createElement(StyledOcticon, { | ||
color: "black", | ||
icon: Link$1 | ||
})); | ||
}; | ||
Anchor.displayName = "Anchor"; | ||
var StyledHeading = styled(Heading)(_templateObject$7()); | ||
var MarkdownHeading = function MarkdownHeading(_ref2) { | ||
var children = _ref2.children, | ||
id = _ref2.id, | ||
rest = _objectWithoutProperties(_ref2, ["children", "id"]); | ||
return React.createElement(StyledHeading, _extends({ | ||
id: id | ||
}, rest), React.createElement(Anchor, { | ||
id: id | ||
}), children); | ||
}; | ||
MarkdownHeading.displayName = "MarkdownHeading"; | ||
/** | ||
* 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 | ||
@@ -803,11 +1266,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, | ||
@@ -817,3 +1280,3 @@ content = props.children; | ||
if (content) { | ||
return React.createElement(Link$1, props); | ||
return React.createElement(Link$2, props); | ||
} | ||
@@ -825,21 +1288,94 @@ | ||
var children = (node ? node.meta.title : null) || href; | ||
return React.createElement(Link$1, props, children); | ||
return React.createElement(Link$2, 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) { | ||
@@ -879,6 +1415,6 @@ var outline = _ref.outline, | ||
function _templateObject$1() { | ||
function _templateObject$8() { | ||
var data = _taggedTemplateLiteral(["\n display: inline-block;\n white-space: nowrap;\n"]); | ||
_templateObject$1 = function _templateObject() { | ||
_templateObject$8 = function _templateObject() { | ||
return data; | ||
@@ -889,3 +1425,3 @@ }; | ||
} | ||
var StyledLabel = styled(BorderBox)(_templateObject$1()); | ||
var StyledLabel = styled(BorderBox)(_templateObject$8()); | ||
var STATUS_COLORS = { | ||
@@ -984,108 +1520,74 @@ stable: 'green.6', | ||
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"; | ||
var PrimerHeader = function PrimerHeader(_ref) { | ||
var root = _ref.root; | ||
return React.createElement(Header, { | ||
title: "Primer", | ||
subtitle: "Blueprints", | ||
root: root | ||
}, React.createElement(Link, { | ||
color: "blue.2", | ||
fontWeight: "bold", | ||
href: "https://primer.style/news" | ||
}, "What's New"), React.createElement(NavDropdown, { | ||
title: "Design" | ||
}, React.createElement(NavItem, { | ||
href: "https://primer.style#design" | ||
}, "Overview"), React.createElement(NavItem, { | ||
href: "https://primer.style/design" | ||
}, "Interface Guidelines"), React.createElement(NavItem, { | ||
href: "https://octicons.github.com/" | ||
}, "Icons"), React.createElement(NavItem, { | ||
href: "https://github.com/primer/presentations" | ||
}, "Presentations")), React.createElement(NavDropdown, { | ||
title: "Development" | ||
}, React.createElement(NavItem, { | ||
href: "https://primer.style#development" | ||
}, "Overview"), React.createElement(NavItem, { | ||
href: "https://primer.style/css" | ||
}, "Primer CSS"), React.createElement(NavItem, { | ||
href: "https://primer.style/components" | ||
}, "Primer Components"), React.createElement(NavItem, { | ||
href: "https://github.com/primer/deploy" | ||
}, "Deploy"), React.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/prototyping" | ||
}, "Prototyping")), React.createElement(NavDropdown, { | ||
direction: "sw", | ||
title: "Tools" | ||
}, React.createElement(NavItem, { | ||
href: "https://primer.style#tools" | ||
}, "Overview"), React.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/atom-packages" | ||
}, "Atom packages"), React.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/docset" | ||
}, "Docs set"), React.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/local-primer" | ||
}, "GitHub local environment"), React.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/linting" | ||
}, "Linting"))); | ||
}; | ||
PrimerHeader.displayName = "PrimerHeader"; | ||
/** | ||
* 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 | ||
@@ -1097,5 +1599,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; | ||
@@ -1112,52 +1614,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, Details, Frame, Header, Link$2 as Link, MarkdownHeading, NavDropdown, NavItem, NavLink, NavList, Outline, PackageHeader, PageLink, PrimerHeader, RouteMatch, Router, Section, Search, SearchInput, SearchItem, SearchResults, 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('styled-components'), require('styled-system'), require('next/link'), require('next/router'), require('lunr'), require('downshift'), require('classnames')) : | ||
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', 'styled-components', 'styled-system', 'next/link', 'next/router', 'lunr', 'downshift', 'classnames'], 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.styled,global.styledSystem,global.NextLink,global.router,global.lunr,global.Downshift,global.classnames)); | ||
}(this, (function (exports,React,ReactDOM,components,Octicon,getConfig,TreeModel,path,Measure,HTMLtoJSX,reactLive,prismGithub_scss,PropTypes,styled,styledSystem,NextLink,router,lunr,Downshift,classnames) { 'use strict'; | ||
@@ -14,5 +14,9 @@ var React__default = 'default' in React ? React['default'] : React; | ||
HTMLtoJSX = HTMLtoJSX && HTMLtoJSX.hasOwnProperty('default') ? HTMLtoJSX['default'] : HTMLtoJSX; | ||
propTypes = propTypes && propTypes.hasOwnProperty('default') ? propTypes['default'] : propTypes; | ||
PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes; | ||
styled = styled && styled.hasOwnProperty('default') ? styled['default'] : styled; | ||
NextLink = NextLink && NextLink.hasOwnProperty('default') ? NextLink['default'] : NextLink; | ||
styled = styled && styled.hasOwnProperty('default') ? styled['default'] : styled; | ||
var router__default = 'default' in router ? router['default'] : router; | ||
lunr = lunr && lunr.hasOwnProperty('default') ? lunr['default'] : lunr; | ||
Downshift = Downshift && Downshift.hasOwnProperty('default') ? Downshift['default'] : Downshift; | ||
classnames = classnames && classnames.hasOwnProperty('default') ? classnames['default'] : classnames; | ||
@@ -74,2 +78,21 @@ function _classCallCheck(instance, Constructor) { | ||
function _objectSpread(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
var ownKeys = Object.keys(source); | ||
if (typeof Object.getOwnPropertySymbols === 'function') { | ||
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(source, sym).enumerable; | ||
})); | ||
} | ||
ownKeys.forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} | ||
return target; | ||
} | ||
function _inherits(subClass, superClass) { | ||
@@ -415,2 +438,29 @@ if (typeof superClass !== "function" && superClass !== null) { | ||
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 = | ||
@@ -703,2 +753,87 @@ /*#__PURE__*/ | ||
function _templateObject2() { | ||
var data = _taggedTemplateLiteral(["\n ", ";\n ", ";\n"]); | ||
_templateObject2 = function _templateObject2() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject() { | ||
var data = _taggedTemplateLiteral(["\n & > summary {\n list-style: none;\n }\n & > summary::-webkit-details-marker {\n display: none;\n }\n"]); | ||
_templateObject = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var DetailsReset = styled('details')(_templateObject()); | ||
function getRenderer(children) { | ||
return typeof children === 'function' ? children : function () { | ||
return children; | ||
}; | ||
} | ||
function DetailsBase(_ref) { | ||
var children = _ref.children, | ||
overlay = _ref.overlay, | ||
_ref$render = _ref.render, | ||
render = _ref$render === void 0 ? getRenderer(children) : _ref$render, | ||
rest = _objectWithoutProperties(_ref, ["children", "overlay", "render"]); | ||
var _useState = React.useState(Boolean(rest.open)), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
open = _useState2[0], | ||
setOpen = _useState2[1]; | ||
function toggle(event) { | ||
if (event) event.preventDefault(); | ||
if (overlay) { | ||
openMenu(); | ||
} else { | ||
setOpen(!open); | ||
} | ||
} | ||
function openMenu() { | ||
if (!open) { | ||
setOpen(true); | ||
document.addEventListener('click', closeMenu); | ||
} | ||
} | ||
function closeMenu() { | ||
setOpen(false); | ||
document.removeEventListener('click', closeMenu); | ||
} | ||
return React__default.createElement(DetailsReset, _extends({}, rest, { | ||
open: open, | ||
overlay: overlay | ||
}), render({ | ||
open: open, | ||
toggle: toggle | ||
})); | ||
} | ||
DetailsBase.displayName = "DetailsBase"; | ||
var Details = styled(DetailsBase)(_templateObject2(), styledSystem.space, styledSystem.color); | ||
Details.defaultProps = { | ||
theme: components.theme, | ||
overlay: false | ||
}; | ||
Details.propTypes = { | ||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), | ||
className: PropTypes.string, | ||
open: PropTypes.bool, | ||
overlay: PropTypes.bool, | ||
render: PropTypes.func, | ||
theme: PropTypes.object | ||
}; | ||
function Link(_ref) { | ||
@@ -716,6 +851,281 @@ var href = _ref.href, | ||
function _templateObject() { | ||
var get = function get(key) { | ||
return styledSystem.themeGet(key, styledSystem.get(components.theme, key)); | ||
}; | ||
var getDirectionStyles = function getDirectionStyles(theme, direction) { | ||
var map = { | ||
w: "\n top: 0;\n right: 100%;\n left: auto;\n width: auto;\n margin-top: 0;\n margin-right: 10px;\n\n &::before {\n top: 10px;\n right: -16px;\n left: auto;\n border-color: transparent;\n border-left-color: ".concat(get('colors.blackfade15')(theme), ";\n }\n\n &::after {\n top: 11px;\n right: -14px;\n left: auto;\n border-color: transparent;\n border-left-color: ").concat(get('colors.white')(theme), ";\n }\n "), | ||
e: "\n top: 0;\n left: 100%;\n width: auto;\n margin-top: 0;\n margin-left: 10px;\n\n &::before {\n top: 10px;\n left: -16px;\n border-color: transparent;\n border-right-color: ".concat(get('colors.blackfade15')(theme), ";\n }\n\n &::after {\n top: 11px;\n left: -14px;\n border-color: transparent;\n border-right-color: ").concat(get('colors.white')(theme), ";\n }\n "), | ||
ne: "\n top: auto;\n bottom: 100%;\n left: 0;\n margin-bottom: 3px;\n\n &::before,\n &::after {\n top: auto;\n right: auto;\n }\n\n &::before {\n bottom: -8px;\n left: 9px;\n border-top: 8px solid ".concat(get('colors.blackfade15')(theme), ";\n border-bottom: 0;\n border-left: 8px solid transparent;\n }\n\n &::after {\n bottom: -7px;\n left: 10px;\n border-top: 7px solid ").concat(get('colors.white')(theme), ";\n border-right: 7px solid transparent;\n border-bottom: 0;\n border-left: 7px solid transparent;\n }\n "), | ||
s: "\n right: 50%;\n left: auto;\n transform: translateX(50%);\n\n &::before {\n top: -16px;\n right: 50%;\n transform: translateX(50%);\n }\n\n &::after {\n top: -14px;\n right: 50%;\n transform: translateX(50%);\n }\n ", | ||
sw: "\n right: 0;\n left: auto;\n\n &::before {\n top: -16px;\n right: 9px;\n left: auto;\n }\n\n &::after {\n top: -14px;\n right: 10px;\n left: auto;\n }\n ", | ||
se: "\n &::before {\n top: -16px;\n left: 9px;\n }\n\n &::after {\n top: -14px;\n left: 10px;\n }\n " | ||
}; | ||
return map[direction]; | ||
}; | ||
function _templateObject$1() { | ||
var data = _taggedTemplateLiteral(["\n color: ", ";\n display: block;\n padding: 0 ", "px;\n line-height: 30px;\n white-space: nowrap;\n &:hover {\n color: ", ";\n background-color: ", ";\n text-decoration: none;\n }\n &:last-child:hover {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n }\n &:first-child:hover {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n }\n"]); | ||
_templateObject$1 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var NavItem = styled(components.Link)(_templateObject$1(), components.theme.colors.blue[2], components.theme.space[3], components.theme.colors.black, components.theme.colors.blue[4]); | ||
function _templateObject$2() { | ||
var data = _taggedTemplateLiteral(["\n box-shadow: 0px 4px 12px rgba(27, 31, 35, 0.15);\n border: 1px solid rgba(219, 237, 255, 0.3);\n border-radius: 4px;\n ", ";\n"]); | ||
_templateObject$2 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var DropdownMenu = styled.div(_templateObject$2(), function (props) { | ||
return props.direction ? getDirectionStyles(props.theme, props.direction) : ''; | ||
}); | ||
function NavDropdown(_ref) { | ||
var children = _ref.children, | ||
title = _ref.title, | ||
_ref$direction = _ref.direction, | ||
direction = _ref$direction === void 0 ? 'se' : _ref$direction; | ||
return React__default.createElement(components.Box, null, React__default.createElement(Details, { | ||
overlay: true, | ||
mx: 3, | ||
render: function render(_ref2) { | ||
var toggle = _ref2.toggle; | ||
return React__default.createElement(React__default.Fragment, null, React__default.createElement(components.Text, { | ||
fontWeight: "bold", | ||
color: "blue.2", | ||
is: "summary", | ||
onClick: toggle | ||
}, title, " ", React__default.createElement(components.StyledOcticon, { | ||
icon: Octicon.ChevronDown | ||
})), React__default.createElement(components.Relative, null, React__default.createElement(DropdownMenu, { | ||
as: components.Absolute, | ||
zIndex: 90, | ||
bg: "black", | ||
direction: direction | ||
}, children))); | ||
} | ||
})); | ||
} | ||
NavDropdown.displayName = "NavDropdown"; | ||
var documents = { | ||
"undefined": { | ||
"content": "import {Box, Heading} from '@primer/components'\nimport {CONTENT_MAX_WIDTH} from '../../src/constants'\n\nexport const Hero = () => (\n <Box bg=\"black\">\n <Box maxWidth={CONTENT_MAX_WIDTH} p={6} mx=\"auto\" mb={3}>\n <Box mt={4} mb={4}>\n <Heading fontWeight=\"bold\" color=\"blue.4\" fontSize={7} pb={3} m={0}>\n Primer Blueprints\n </Heading>\n </Box>\n </Box>\n </Box>\n)\n\n# Introduction\n\nThese components are to be used to build documentation sites across our different Primer projects.\n" | ||
}, | ||
"content-components/clipboard-copy": { | ||
"title": "ClipboardCopy", | ||
"path": "content-components/clipboard-copy", | ||
"content": "\nUse the ClipboardCopy component to add copying functionality next to code blocks in documentation.\nThe `value` prop must be provided with the current value of the code block.\n\n```.jsx\n<ClipboardCopy value={'hihihi'}/>\n\n```\n\n\n## Component props\n\n| Name | Type | Default | Description |\n| :- | :- | :-: | :- |\n| value | String | | The content that will be added to the user's clipboard when clicked.\n" | ||
}, | ||
"content-components/contributors": { | ||
"title": "Contributors", | ||
"path": "content-components/contributors", | ||
"content": "\nUse the Contributors component to add contributor credit to the bottom of any docs page. With a provided file path & repo path, the component will fetch commit data from the GitHub API and display all contributors to that file. In instances where you'd like to add additional contributor credits that are not reflected in the commit data (for example, if a repository has been moved and the git history lost) you can use the `contributor` prop to add additional contributors.\n\n\n```.jsx\n<Contributors\n filePath='README.md'\n repoPath='primer/components'\n contributors={[{login: 'emplums'}, {login: 'broccolini'}]}\n/>\n```\n\n## Component props\n\n| Name | Type | Default | Description |\n| :- | :- | :-: | :- |\n| filePath | String | | The path to the file you'd like to pull contributor data from. |\n| repoPath | String | | The repository path on GitHub. For example: `primer/components` |\n| contributors | Array | | Prop for adding additional contributors not reflected in commit history. Format is an array of objects with a `login` key. Ex. `[{login: 'emplums'}, {login: 'broccolini'}]` |\n" | ||
}, | ||
"content-components/code-example": { | ||
"title": "CodeExample", | ||
"path": "content-components/code-example", | ||
"content": "\nUse the CodeExample component to wrap HTML code examples. This component was created to prevent CSS from our markdown styles from bleeding over into examples by displaying examples in an iframe.\n\nThis component can also be passed to the component prop of your MDXProvider to replace all code blocks with CodeExample like so:\n\n```\nconst components = {\n code: CodeExample\n}\n\nreturn (\n <MDXProvider components={components}>\n <Component {...page} />\n </MDXProvider>\n)\n\n```\n\n```.jsx\n<CodeExample>\n <div>hello world!</div>\n</CodeExample>\n\n```\n" | ||
}, | ||
"content-components/frame": { | ||
"title": "Frame", | ||
"path": "content-components/frame", | ||
"content": "\nThe Frame component wraps children components in an iframe\n\n\n```.jsx\n<Frame minHeight={50}>\n <Text>Hi</Text>\n</Frame>\n```\n\n## Component props\n\n| Name | Type | Default | Description |\n| :- | :- | :-: | :- |\n| minHeight | String or Number | 0 | minHeight of iframe\n| border | String | 0 | border for element\n| borderRadius | String or Number | 0 | borderRadius for element\n| width | String or Number | 100% | width of iframe\n" | ||
}, | ||
"content-components/link": { | ||
"title": "Link", | ||
"path": "content-components/link", | ||
"content": "\nUse the Link component to add links within documentation. The link component wraps the standard Primer link with Next's link component for easy routing in Next.js applications.\n\n```.jsx\n<Link href=\"https://github.com/primer\">Primer</Link>\n\n```\n" | ||
}, | ||
"content-components/index": { | ||
"title": "Content Components", | ||
"path": "content-components/index", | ||
"content": "\n Components are reusable React components that can be used to build UI for our documentation sites.\n" | ||
}, | ||
"navigation-components/index": { | ||
"title": "Navigation Components", | ||
"path": "navigation-components/index", | ||
"content": "\nNavigation components can be used to build navigation on documentation sites\n" | ||
}, | ||
"navigation-components/header": { | ||
"title": "Header", | ||
"path": "navigation-components/header", | ||
"keywords": ["navigation", "header"], | ||
"content": "\nUse Header to provide a top navigation for your site. Children of `Header` will be rendered on the right side of the component. Children should be top level navigation links. The `title` prop specifies what should be rendered to the right of the GitHub Mark. The `root` prop specifies where you'd like the GitHub Mark to link to. Leave blank if you'd like it to route to `/`.\n```.jsx\n<Header title=\"Hello world!\" root='/blueprints'>\n <NavDropdown title={`What's new`}>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Design'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Development'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Content'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n <NavDropdown title='Tools'>\n <NavItem>Overview</NavItem>\n <NavItem>Interface Guidelines</NavItem>\n <NavItem>Octicons</NavItem>\n </NavDropdown>\n</Header>\n```\n" | ||
}, | ||
"navigation-components/nav-link": { | ||
"title": "NavLink", | ||
"path": "navigation-components/nav-link", | ||
"content": "\nThe NavLink component is a PageLink that turns black when it's href matches the current path. NavLinks are typically used in sidebar sub-navigation.\n\n\n```.jsx\nMatches current path:\n<NavLink mb={4} href='/blueprints/navigation-components/NavLink' />\n\nDoes not match current path:\n<NavLink href='/blueprints/navigation-components/Section' />\n```\n" | ||
}, | ||
"navigation-components/nav-list": { | ||
"title": "NavList", | ||
"path": "navigation-components/nav-list", | ||
"content": "\n\nA `<NavList>` renders a `<Section.Link>` for the given `path` and looks up the\npath in the page tree. If a node is found, it renders a `<NavLink>` for each\nof the node's children.\n\nThe automatically generated page links in a NavList are sorted alphabetically by either the sort_title or title frontmatter keys. If a page has a non-empty sort_title, that value is used only to determine its position in the list; otherwise, the title determines their sort order. The title key is always used as a page's link text.\n\n\n```.jsx\n<NavList path='/blueprints/content-components'/>\n```\n" | ||
}, | ||
"navigation-components/page-link": { | ||
"title": "PageLink", | ||
"path": "navigation-components/page-link", | ||
"content": "\nThe PageLink component takes an `href` and optional `children`.\nIf no `children` are provided, we look up the \"node\" of the corresponding\npage in the tree (the one whose `path` matches the given `href`) and use\nthat node's `title` frontmatter key. In other words, given the following\npages/foo/bar.md:\n\n```md\n---\ntitle: Foo Bar\n---\n```\n\nThe following instance of PageLink should render a link to \"/foo/bar\" with\n\"Foo Bar\" as its text:\n```.jsx\n<PageLink href=\"/foo/bar\" />\n```\n" | ||
}, | ||
"navigation-components/section": { | ||
"title": "Section", | ||
"path": "navigation-components/section", | ||
"content": "\nA `Section` gets a `path` and optional children. If it has children it will\nrender those and prepend each child's `href` prop with the provided `path`.\nThis means that you can do:\n\n```.jsx\n<Section path=\"/section\">\n <Section.Link href=\"foo\">Links to /section/foo</Section.Link>\n</Section>\n```\n\nIf no children are provided, it renders a [`NavList`](/blueprints/nav-components/NavList) with the provided\n`path`.\n" | ||
}, | ||
"navigation-components/route-match": { | ||
"title": "RouteMatch", | ||
"path": "navigation-components/route-match", | ||
"content": "\nUse `RouteMatch` to conditionally render content without a wrapper\nelement when contained directly in a `Router`. `RouteMatch` is most commonly used to conditionally render a chunk of side navigation links.\n\n\n```.jsx\n<Router>\n <RouteMatch path=\"/blueprints/navigation-components\">\n <Box>this will only show up on pages whose path begins with \"/blueprints/navigation-components\"</Box>\n </RouteMatch>\n <RouteMatch path=\"/blueprints/content-components\">\n <Box>this will only show up on pages whose path begins with \"/blueprints/content-components\"</Box>\n </RouteMatch>\n</Router>\n\n```\n" | ||
}, | ||
"navigation-components/side-nav": { | ||
"title": "SideNav", | ||
"path": "navigation-components/side-nav", | ||
"content": "\n\nContainer component that takes children and nests them in a Router with layout styling. The `SideNav` of this site uses `Section` components to show both the Content Components and Navigation Components sections. See [the `Section` docs](/blueprints/navigation-components/section) for more details.\n\nYou may also use the `RouteMatch` components in your `SideNav` to conditionally show specific navigation links in the SideNav depending on where you are on the docs site. See [`RouteMatch` docs](/blueprints/navigation-components/section) for more details.\n\n\n```.jsx\n<SideNav>\n <RouteMatch path=\"/blueprints\">\n <Section path=\"content-components\" />\n </RouteMatch>\n</SideNav>\n```\n" | ||
}, | ||
"tools/index": { | ||
"title": "Tools", | ||
"path": "tools/index", | ||
"content": "\nComing soon\n" | ||
} | ||
}; | ||
function _templateObject$3() { | ||
var data = _taggedTemplateLiteral(["\n display: block;\n text-decoration: none;\n color: ", ";\n background-color: ", ";\n padding: 8px;\n"]); | ||
_templateObject$3 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var SearchItem = styled(Link)(_templateObject$3(), function (props) { | ||
return props.isHighlighted ? '#fff' : '#24292e'; | ||
}, function (props) { | ||
return props.isHighlighted ? '#0366d6' : '#fff'; | ||
}); | ||
function _templateObject$4() { | ||
var data = _taggedTemplateLiteral(["\n color: #fff;\n background-color: rgba(255, 255, 255, 0.07);\n border: 1px;\n border: 1px solid transparent;\n &:focus,\n &:active {\n border: 1px solid rgba(255, 255, 255, 0.15);\n outline: none;\n box-shadow: none;\n }\n"]); | ||
_templateObject$4 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var SearchInput = styled(components.TextInput)(_templateObject$4()); | ||
function _templateObject$5() { | ||
var data = _taggedTemplateLiteral(["\n box-shadow: 0 1px 5px rgba(27, 31, 35, 0.15);\n width: 100%;\n overflow: auto;\n right: 0;\n background-color: #fff;\n display: ", ";\n position: absolute;\n\n @media (min-width: 1012px) {\n width: 0;\n min-width: 320px;\n height: auto;\n max-height: 240px;\n border-radius: 3px;\n border: 1px solid #e1e4e8;\n padding-bottom: 0;\n }\n"]); | ||
_templateObject$5 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var SearchResults = styled.div(_templateObject$5(), function (props) { | ||
return props.open ? 'block' : 'none'; | ||
}); | ||
function Search(_ref) { | ||
var root = _ref.root; | ||
var idx = lunr(function () { | ||
this.ref('path'); //eslint-disable-line | ||
this.field('title'); //eslint-disable-line | ||
this.field('content'); //eslint-disable-line | ||
this.field('keywords'); //eslint-disable-line | ||
var _arr = Object.values(documents); | ||
for (var _i = 0; _i < _arr.length; _i++) { | ||
var doc = _arr[_i]; | ||
this.add(doc); //eslint-disable-line | ||
} | ||
}); | ||
var _useState = React.useState([]), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
results = _useState2[0], | ||
setResults = _useState2[1]; | ||
var onChange = function onChange(e) { | ||
if (e.target) { | ||
setResults(idx.search(e.target.value)); | ||
} | ||
}; | ||
var renderResults = function renderResults(selectedItem, getItemProps, highlightedIndex) { | ||
return results.map(function (result, index) { | ||
var doc = documents[result.ref]; | ||
return React__default.createElement(SearchItem //eslint-disable-line | ||
, getItemProps({ | ||
item: result, | ||
index: index, | ||
key: result.ref, | ||
href: "/".concat(root, "/").concat(doc.path), | ||
isHighlighted: highlightedIndex === index | ||
}), doc.title); | ||
}); | ||
}; | ||
function stateReducer(state, changes) { | ||
switch (changes.type) { | ||
case Downshift.stateChangeTypes.keyDownEnter: | ||
case Downshift.stateChangeTypes.clickItem: | ||
return _objectSpread({}, changes, { | ||
inputValue: '' | ||
}); | ||
default: | ||
return changes; | ||
} | ||
} | ||
return React__default.createElement(components.Box, { | ||
is: components.Relative | ||
}, React__default.createElement(Downshift, { | ||
onChange: onChange, | ||
itemToString: function itemToString(item) { | ||
return item ? documents[item.ref].title : ''; | ||
}, | ||
stateReducer: stateReducer | ||
}, function (_ref2) { | ||
var getInputProps = _ref2.getInputProps, | ||
getMenuProps = _ref2.getMenuProps, | ||
getLabelProps = _ref2.getLabelProps, | ||
getItemProps = _ref2.getItemProps, | ||
isOpen = _ref2.isOpen, | ||
highlightedIndex = _ref2.highlightedIndex, | ||
selectedItem = _ref2.selectedItem; | ||
return React__default.createElement("div", null, React__default.createElement("label", _extends({ | ||
hidden: true | ||
}, getLabelProps()), ' ', "//eslint-disable-line Search docs"), React__default.createElement(SearchInput, _extends({ | ||
placeholder: "Search" | ||
}, getInputProps({ | ||
onChange: onChange | ||
}))), React__default.createElement(SearchResults, _extends({ | ||
open: isOpen | ||
}, getMenuProps()), renderResults(selectedItem, getItemProps, highlightedIndex))); | ||
})); | ||
} | ||
Search.displayName = "Search"; | ||
function _templateObject$6() { | ||
var data = _taggedTemplateLiteral(["\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n"]); | ||
_templateObject = function _templateObject() { | ||
_templateObject$6 = function _templateObject() { | ||
return data; | ||
@@ -726,3 +1136,3 @@ }; | ||
} | ||
var BoxShadow = styled(components.Box)(_templateObject()); | ||
var BoxShadow = styled(components.Box)(_templateObject$6()); | ||
@@ -739,2 +1149,3 @@ var HeaderText = function HeaderText(props) { | ||
var title = _ref.title, | ||
subtitle = _ref.subtitle, | ||
root = _ref.root, | ||
@@ -752,17 +1163,30 @@ children = _ref.children; | ||
justifyContent: "space-between" | ||
}, React__default.createElement(components.Flex, { | ||
alignItems: "center", | ||
justifyContent: "center" | ||
}, React__default.createElement(Link, { | ||
href: "/".concat(root), | ||
href: "https://primer.style/".concat(root), | ||
color: "white", | ||
ml: 3 | ||
mx: 3 | ||
}, React__default.createElement(components.Flex, { | ||
alignItems: "center", | ||
justifyContent: "center" | ||
}, React__default.createElement(Octicon__default, { | ||
alignItems: "center" | ||
}, React__default.createElement(components.StyledOcticon, { | ||
color: "blue.4", | ||
icon: Octicon.MarkGithub, | ||
size: "medium" | ||
}), React__default.createElement(HeaderText, { | ||
ml: 3 | ||
}, title))), React__default.createElement(components.Box, { | ||
display: ['none', 'none', 'block'] | ||
}, React__default.createElement(HeaderText, null, children)), React__default.createElement(components.Box, { | ||
ml: 3, | ||
color: "blue.4", | ||
fontFamily: "mono" | ||
}, title), React__default.createElement(components.StyledOcticon, { | ||
icon: Octicon.ChevronRight, | ||
mx: 2, | ||
color: "blue.2" | ||
}), React__default.createElement(HeaderText, { | ||
fontWeight: "bold" | ||
}, subtitle))), React__default.createElement(Search, { | ||
root: root | ||
})), React__default.createElement(components.Box, { | ||
display: ['none', 'none', 'flex'] | ||
}, children), React__default.createElement(components.Box, { | ||
display: ['block', 'block', 'none'] | ||
@@ -790,4 +1214,43 @@ }, React__default.createElement(Link, { | ||
function _templateObject$7() { | ||
var data = _taggedTemplateLiteral(["\n .anchor {\n display: none;\n }\n &:hover .anchor {\n display: inline-block;\n }\n &:focus .anchor {\n display: inline-block;\n }\n"]); | ||
_templateObject$7 = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var Anchor = function Anchor(_ref) { | ||
var id = _ref.id, | ||
className = _ref.className; | ||
return React__default.createElement("a", { | ||
href: "#".concat(id), | ||
className: classnames('anchor', className) | ||
}, React__default.createElement(components.StyledOcticon, { | ||
color: "black", | ||
icon: Octicon.Link | ||
})); | ||
}; | ||
Anchor.displayName = "Anchor"; | ||
var StyledHeading = styled(components.Heading)(_templateObject$7()); | ||
var MarkdownHeading = function MarkdownHeading(_ref2) { | ||
var children = _ref2.children, | ||
id = _ref2.id, | ||
rest = _objectWithoutProperties(_ref2, ["children", "id"]); | ||
return React__default.createElement(StyledHeading, _extends({ | ||
id: id | ||
}, rest), React__default.createElement(Anchor, { | ||
id: id | ||
}), children); | ||
}; | ||
MarkdownHeading.displayName = "MarkdownHeading"; | ||
/** | ||
* 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 | ||
@@ -804,11 +1267,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, | ||
@@ -827,19 +1290,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) { | ||
@@ -879,6 +1415,6 @@ var outline = _ref.outline, | ||
function _templateObject$1() { | ||
function _templateObject$8() { | ||
var data = _taggedTemplateLiteral(["\n display: inline-block;\n white-space: nowrap;\n"]); | ||
_templateObject$1 = function _templateObject() { | ||
_templateObject$8 = function _templateObject() { | ||
return data; | ||
@@ -889,3 +1425,3 @@ }; | ||
} | ||
var StyledLabel = styled(components.BorderBox)(_templateObject$1()); | ||
var StyledLabel = styled(components.BorderBox)(_templateObject$8()); | ||
var STATUS_COLORS = { | ||
@@ -984,108 +1520,74 @@ stable: 'green.6', | ||
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"; | ||
var PrimerHeader = function PrimerHeader(_ref) { | ||
var root = _ref.root; | ||
return React__default.createElement(Header, { | ||
title: "Primer", | ||
subtitle: "Blueprints", | ||
root: root | ||
}, React__default.createElement(components.Link, { | ||
color: "blue.2", | ||
fontWeight: "bold", | ||
href: "https://primer.style/news" | ||
}, "What's New"), React__default.createElement(NavDropdown, { | ||
title: "Design" | ||
}, React__default.createElement(NavItem, { | ||
href: "https://primer.style#design" | ||
}, "Overview"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/design" | ||
}, "Interface Guidelines"), React__default.createElement(NavItem, { | ||
href: "https://octicons.github.com/" | ||
}, "Icons"), React__default.createElement(NavItem, { | ||
href: "https://github.com/primer/presentations" | ||
}, "Presentations")), React__default.createElement(NavDropdown, { | ||
title: "Development" | ||
}, React__default.createElement(NavItem, { | ||
href: "https://primer.style#development" | ||
}, "Overview"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/css" | ||
}, "Primer CSS"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/components" | ||
}, "Primer Components"), React__default.createElement(NavItem, { | ||
href: "https://github.com/primer/deploy" | ||
}, "Deploy"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/prototyping" | ||
}, "Prototyping")), React__default.createElement(NavDropdown, { | ||
direction: "sw", | ||
title: "Tools" | ||
}, React__default.createElement(NavItem, { | ||
href: "https://primer.style#tools" | ||
}, "Overview"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/atom-packages" | ||
}, "Atom packages"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/docset" | ||
}, "Docs set"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/local-primer" | ||
}, "GitHub local environment"), React__default.createElement(NavItem, { | ||
href: "https://primer.style/css/tools/linting" | ||
}, "Linting"))); | ||
}; | ||
PrimerHeader.displayName = "PrimerHeader"; | ||
/** | ||
* 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 | ||
@@ -1097,5 +1599,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; | ||
@@ -1112,62 +1614,39 @@ 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; | ||
exports.CodeExample = CodeExample; | ||
exports.Contributors = Contributors; | ||
exports.Details = Details; | ||
exports.Frame = Frame; | ||
exports.Header = Header; | ||
exports.Link = Link; | ||
exports.MarkdownHeading = MarkdownHeading; | ||
exports.NavDropdown = NavDropdown; | ||
exports.NavItem = NavItem; | ||
exports.NavLink = NavLink; | ||
exports.NodeLink = NodeLink; | ||
exports.NavList = NavList; | ||
exports.Outline = Outline; | ||
exports.PackageHeader = PackageHeader; | ||
exports.PageLink = PageLink; | ||
exports.PrimerHeader = PrimerHeader; | ||
exports.RouteMatch = RouteMatch; | ||
exports.Router = Router; | ||
exports.Section = Section; | ||
exports.Search = Search; | ||
exports.SearchInput = SearchInput; | ||
exports.SearchItem = SearchItem; | ||
exports.SearchResults = SearchResults; | ||
exports.SideNav = SideNav; | ||
@@ -1185,2 +1664,5 @@ exports.StatusLabel = StatusLabel; | ||
exports.rootPage = rootPage; | ||
exports.sortCompare = sortCompare; | ||
exports.nodeSort = nodeSort; | ||
exports.addPath = addPath; | ||
@@ -1187,0 +1669,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
{ | ||
"name": "@primer/blueprints", | ||
"version": "0.0.0-16066f1", | ||
"version": "0.0.0-190a0c6", | ||
"description": "Components for GitHub Documentation Sites", | ||
@@ -35,3 +35,3 @@ "main": "dist/index.umd.js", | ||
"@mdx-js/tag": "0.15.0", | ||
"@primer/components": "^8.2.0-beta", | ||
"@primer/components": "11.0.0", | ||
"@svgr/webpack": "2.4.1", | ||
@@ -86,3 +86,4 @@ "@zeit/next-css": "^1.0.1", | ||
"sass.macro": "0.1.0", | ||
"styled-components": "^4.1.2", | ||
"styled-system": "4.0.4", | ||
"styled-components": "4.1.3", | ||
"title-case": "^2.1.1", | ||
@@ -95,3 +96,9 @@ "tree-model": "^1.0.7", | ||
"unist-util-visit": "^1.4.0" | ||
}, | ||
"dependencies": { | ||
"classnames": "2.2.6", | ||
"downshift": "3.2.7", | ||
"lunr": "2.3.6", | ||
"uuid": "3.3.2" | ||
} | ||
} |
export {default as ClipboardCopy} from './ClipboardCopy' | ||
export {default as CodeExample} from './CodeExample' | ||
export {default as Contributors} from './Contributors' | ||
export {default as Details} from './Details' | ||
export {default as Frame} from './Frame' | ||
export {default as Header} from './Header' | ||
export {default as Link} from './Link' | ||
export {default as MarkdownHeading} from './MarkdownHeading' | ||
export {default as NavDropdown} from './NavDropdown' | ||
export {default as NavItem} from './NavItem' | ||
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 PrimerHeader} from './PrimerHeader' | ||
export {default as RouteMatch} from './RouteMatch' | ||
export {default as Router} from './Router' | ||
export {default as Section} from './Section' | ||
export {default as Search} from './Search' | ||
export {default as SearchInput} from './SearchInput' | ||
export {default as SearchItem} from './SearchItem' | ||
export {default as SearchResults} from './SearchResults' | ||
export {default as SideNav} from './SideNav' | ||
export {default as StatusLabel} from './StatusLabel' |
@@ -0,1 +1,6 @@ | ||
import {themeGet, get as getKey} from 'styled-system' | ||
import {theme} from '@primer/components' | ||
export const get = key => themeGet(key, getKey(theme, key)) | ||
export const CONTENT_MAX_WIDTH = 1012 |
import React from 'react' | ||
import PropTypes from 'prop-types' | ||
import styled from 'styled-components' | ||
import Octicon, {MarkGithub} from '@githubprimer/octicons-react' | ||
import {Text, Flex, Sticky, BorderBox, Box} from '@primer/components' | ||
import {MarkGithub, ChevronRight} from '@githubprimer/octicons-react' | ||
import {Text, Flex, Sticky, BorderBox, Box, StyledOcticon} from '@primer/components' | ||
import Link from './Link' | ||
import NavDropdown from './NavDropdown' | ||
import Search from './Search' | ||
@@ -14,14 +16,20 @@ const BoxShadow = styled(Box)` | ||
const Header = ({title, root, children}) => ( | ||
const Header = ({title, subtitle, root, children}) => ( | ||
<Sticky zIndex={100}> | ||
<BoxShadow py={3} bg="gray.9" color="white"> | ||
<Flex className="p-responsive" alignItems="center" justifyContent="space-between"> | ||
<Link href={`/${root}`} color="white" ml={3}> | ||
<Flex alignItems="center" justifyContent="center"> | ||
<Octicon icon={MarkGithub} size="medium" /> | ||
<HeaderText ml={3}>{title}</HeaderText> | ||
</Flex> | ||
</Link> | ||
<Box display={['none', 'none', 'block']}> | ||
<HeaderText>{children}</HeaderText> | ||
<Flex alignItems="center" justifyContent="center"> | ||
<Link href={`https://primer.style/${root}`} color="white" mx={3}> | ||
<Flex alignItems='center'> | ||
<StyledOcticon color='blue.4' icon={MarkGithub} size="medium" /> | ||
<HeaderText ml={3} color='blue.4' fontFamily='mono'>{title}</HeaderText> | ||
<StyledOcticon icon={ChevronRight} mx={2} color='blue.2'/> | ||
<HeaderText fontWeight='bold'>{subtitle}</HeaderText> | ||
</Flex> | ||
</Link> | ||
<Search root={root}/> | ||
</Flex> | ||
<Box display={['none', 'none', 'flex']}> | ||
{children} | ||
</Box> | ||
@@ -28,0 +36,0 @@ <Box display={['block', 'block', 'none']}> |
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) | ||
} |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
160734
36
4117
4
62
5
+ Addedclassnames@2.2.6
+ Addeddownshift@3.2.7
+ Addedlunr@2.3.6
+ Addeduuid@3.3.2
+ Added@babel/runtime@7.26.9(transitive)
+ Addedclassnames@2.2.6(transitive)
+ Addedcompute-scroll-into-view@1.0.20(transitive)
+ Addeddownshift@3.2.7(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedlunr@2.3.6(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedprop-types@15.8.1(transitive)
+ Addedreact@19.0.0(transitive)
+ Addedreact-is@16.13.1(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
+ Addeduuid@3.3.2(transitive)