Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
_site
dist/
node_modules/
searchIndex.js
16 changes: 10 additions & 6 deletions docs/CodeExample.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React from 'react'
import HTMLtoJSX from 'html-2-jsx'
import styled from 'styled-components'
import {Absolute, BorderBox, Box, StyledOcticon as Octicon, Relative, Text} from '@primer/components'
import {LiveEditor, LiveError, LivePreview, LiveProvider} from 'react-live'
import {getIconByName} from '@githubprimer/octicons-react'
import ClipboardCopy from './ClipboardCopy'
import Frame from './Frame'
import CodeExampleStyles from './CodeExampleStyles'

import 'prism-github/prism-github.scss'
const StyledLiveProvider = styled(LiveProvider)`
${CodeExampleStyles}
`

const LANG_PATTERN = /\blanguage-\.?(jsx|html)\b/

Expand All @@ -33,20 +37,20 @@ export default function CodeExample(props) {
mountStylesheet: false
}
return (
<LiveProvider {...liveProps}>
<StyledLiveProvider {...liveProps}>
<BorderBox {...rest}>
<BorderBox bg="white" border={0} borderBottom={1} borderRadius={0}>
<Frame>
<LivePreview />
</Frame>
</BorderBox>
<Box is={Relative} bg="gray.1" p={3}>
<Box as={Relative} bg="gray.1" p={3}>
<LiveEditor style={{margin: 0, padding: 0}} />
<Absolute right={0} top={0} m={3}>
<ClipboardCopy value={source} />
</Absolute>
<Text
is={LiveError}
as={LiveError}
fontFamily="mono"
style={{
overflow: 'auto',
Expand All @@ -55,15 +59,15 @@ export default function CodeExample(props) {
/>
</Box>
</BorderBox>
</LiveProvider>
</StyledLiveProvider>
)
} else {
const rest = {
children,
dangerouslySetInnerHTML
}
// eslint-disable-next-line react/no-danger-with-children
return <BorderBox data-source={source} is="pre" {...rest} />
return <BorderBox data-source={source} as="pre" {...rest} />
}
}

Expand Down
80 changes: 80 additions & 0 deletions docs/CodeExampleStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const styles = `
code,
code[class*='language-'],
pre[class*='language-'] {
color: #333;
text-align: left;
white-space: pre;
word-spacing: normal;
tab-size: 4;
hyphens: none;
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
line-height: 1.4;
direction: ltr;
cursor: text;
}

pre[class*='language-'] {
overflow: auto;
margin: 1em 0;
padding: 1.2em;
border-radius: 3px;
font-size: 85%;
}

p code,
li code,
table code {
margin: 0;
border-radius: 3px;
padding: 0.2em 0;
font-size: 85%;
}
p code:before, p code:after,
li code:before,
li code:after,
table code:before,
table code:after {
letter-spacing: -0.2em;
content: "00a0";
}

code,
:not(pre) > code[class*='language-'],
pre[class*='language-'] {
background: #f7f7f7;
}

:not(pre) > code[class*='language-'] {
padding: 0.1em;
border-radius: 0.3em;
}

.token.comment, .token.prolog, .token.doctype, .token.cdata {
color: #969896;
}
.token.punctuation, .token.string, .token.atrule, .token.attr-value {
color: #183691;
}
.token.property, .token.tag {
color: #63a35c;
}
.token.boolean, .token.number {
color: #0086b3;
}
.token.selector, .token.attr-name, .token.attr-value .punctuation:first-child, .token.keyword, .token.regex, .token.important {
color: #a71d5d;
}
.token.operator, .token.entity, .token.url, .language-css .token.string {
color: #a71d5d;
}
.token.entity {
cursor: help;
}

.namespace {
opacity: 0.7;
}
`

export default styles
101 changes: 101 additions & 0 deletions docs/Contributors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React, {useEffect, useState} from 'react'
import PropTypes from 'prop-types'
import {Link, Text, Avatar, Flex} from '@primer/components'

function generateContributors(authors) {
const logins = []
const uniqueAuthors = authors.filter(author => {
if (logins.includes(author.login)) {
return false
} else {
logins.push(author.login)
return true
}
})
return uniqueAuthors.map((author, i) => (
<>
<Link href={`https://github.com/${author.login}`}>{author.login}</Link>
{authors.length > 1 && authors.length - 1 !== i && ', '}
</>
))
}

function generateLastEdited(lastAuthor) {
if (lastAuthor) {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
]
const day = lastAuthor.time.getDate()
const month = months[lastAuthor.time.getMonth()]
const year = lastAuthor.time.getFullYear()
return (
<Flex alignItems="center">
<Text fontWeight="bold" lineHeight={2} mr={1}>
Last edited by:{' '}
</Text>
<Avatar src={lastAuthor.avatar} mr={1} />
<Text>
<Link href={`https://github.com/${lastAuthor.login}`}> {lastAuthor.login}</Link> on{' '}
<Link color="gray.5" href={lastAuthor.commitUrl}>{`${month} ${day}, ${year}`}</Link>
</Text>
</Flex>
)
}
}

const Contributors = ({filePath, repoPath, contributors}) => {
const [authors, setAuthors] = useState([])
useEffect(() => {
const url = `https://api.github.com/repos/${repoPath}/commits?path=${filePath}`
fetch(url)
.then(response => response.json())
.then(commits => {
const commitData = []
const ids = []
for (let i = 0; i < commits.length; i++) {
if (!ids.includes(commits[i].author.id)) {
commitData.push({
login: commits[i].author.login,
avatar: commits[i].author.avatar_url,
time: new Date(commits[i].commit.author.date),
commitUrl: commits[i].html_url
})
ids.push(commits[i].author.id)
}
}
setAuthors(commitData)
})
}, [filePath])

return (
<Text fontSize={1}>
<Text fontWeight="bold" lineHeight={2}>
Contributors:{' '}
</Text>
{generateContributors([...contributors, ...authors])}
{generateLastEdited(authors[0])}
</Text>
)
}

Contributors.defaultProps = {
contributors: []
}

Contributors.propTypes = {
contributors: PropTypes.object.isRequired,
filePath: PropTypes.string.isRequired,
repoPath: PropTypes.string.isRequired
}
export default Contributors
69 changes: 69 additions & 0 deletions docs/Details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, {useState} from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {theme} from '@primer/components'
import {space, color} from 'styled-system'

const DetailsReset = styled('details')`
cursor: pointer;
& > summary {
list-style: none;
}
& > summary::-webkit-details-marker {
display: none;
}
`
function getRenderer(children) {
return typeof children === 'function' ? children : () => children
}

function DetailsBase({children, overlay, render = getRenderer(children), ...rest}) {
const [open, setOpen] = useState(Boolean(rest.open))

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 (
<DetailsReset {...rest} open={open} overlay={overlay}>
{render({open, toggle})}
</DetailsReset>
)
}

const Details = styled(DetailsBase)`
${space};
${color};
`

Details.defaultProps = {
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
}

export default Details
7 changes: 1 addition & 6 deletions docs/Frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {assetPrefix} from './utils'

export default class Frame extends React.Component {
static defaultProps = {
display: 'block',
border: 0,
borderRadius: 0,
minHeight: 0,
Expand Down Expand Up @@ -40,11 +39,7 @@ export default class Frame extends React.Component {
getBody(children) {
return (
<Measure bounds onResize={rect => this.setHeight(rect.bounds.height)}>
{({measureRef}) => (
<div ref={measureRef} className="p-3 overflow-auto">
{children}
</div>
)}
{({measureRef}) => <div ref={measureRef}>{children}</div>}
</Measure>
)
}
Expand Down
Loading