The CSS in the project is relatively difficult to change. While it is very DRY, it relies heavily on inheritance. It's difficult to make changes in the markup modal without it also affecting styles elsewhere. [styled-components](https://www.styled-components.com/) is one of the leading CSS-in-JS libraries. By reducing dependency on global state and CSS inheritance, styles become explicit and are easier to inspect and change. It's also convenient that styles can be embedded with the components they modify. At runtime, the library creates CSS classes, so it's pretty efficient. We were using a little bit of [styled-jsx](https://github.com/zeit/styled-jsx) before, which ships with Next.js, though styled-components is more widely used and I've had good experiences with it all around. In a few cases I've duplicated styles where it feels more natural to do that: for example, `text-align: center` is duplicated in `Main` and `MarkupModal`. Much of this is a refactor, though there are a few visual changes, particularly in the markup modal and the style examples.
361 lines
9.6 KiB
JavaScript
361 lines
9.6 KiB
JavaScript
import React, { Fragment } from 'react'
|
|
import PropTypes from 'prop-types'
|
|
import styled from 'styled-components'
|
|
import { staticBadgeUrl } from '../lib/badge-url'
|
|
import { advertisedStyles, logos } from '../../supported-features.json'
|
|
import StaticBadgeMaker from './static-badge-maker'
|
|
import DynamicBadgeMaker from './dynamic-badge-maker'
|
|
import { H2, H3, Badge, VerticalSpace } from './common'
|
|
import { Snippet, StyledCode } from './snippet'
|
|
|
|
const LogoName = styled.span`
|
|
white-space: nowrap;
|
|
`
|
|
|
|
const Lhs = styled.td`
|
|
text-align: right;
|
|
`
|
|
|
|
const EscapingRuleTable = styled.table`
|
|
margin: auto;
|
|
`
|
|
|
|
const QueryParamTable = styled.table`
|
|
min-width: 50%;
|
|
margin: auto;
|
|
table-layout: fixed;
|
|
border-spacing: 20px 10px;
|
|
`
|
|
|
|
const QueryParamSyntax = styled.td`
|
|
max-width: 300px;
|
|
text-align: left;
|
|
`
|
|
|
|
const QueryParamDocumentation = styled.td`
|
|
max-width: 600px;
|
|
text-align: left;
|
|
`
|
|
|
|
const QueryParam = ({ snippet, documentation }) => (
|
|
<tr>
|
|
<QueryParamSyntax>
|
|
<Snippet snippet={snippet} />
|
|
</QueryParamSyntax>
|
|
<QueryParamDocumentation>{documentation}</QueryParamDocumentation>
|
|
</tr>
|
|
)
|
|
QueryParam.propTypes = {
|
|
snippet: PropTypes.string.isRequired,
|
|
documentation: PropTypes.element.isRequired,
|
|
}
|
|
|
|
const EscapingConversion = ({ lhs, rhs }) => (
|
|
<tr>
|
|
<Lhs>{lhs}</Lhs>
|
|
<td>→</td>
|
|
<td>{rhs}</td>
|
|
</tr>
|
|
)
|
|
EscapingConversion.propTypes = {
|
|
lhs: PropTypes.element.isRequired,
|
|
rhs: PropTypes.element.isRequired,
|
|
}
|
|
|
|
export default class Usage extends React.PureComponent {
|
|
static propTypes = {
|
|
baseUrl: PropTypes.string.isRequired,
|
|
}
|
|
|
|
renderColorExamples() {
|
|
const { baseUrl } = this.props
|
|
const colors = [
|
|
'brightgreen',
|
|
'green',
|
|
'yellowgreen',
|
|
'yellow',
|
|
'orange',
|
|
'red',
|
|
'lightgrey',
|
|
'blue',
|
|
'ff69b4',
|
|
]
|
|
return (
|
|
<p>
|
|
{colors.map((color, i) => (
|
|
<Fragment key={i}>
|
|
<Badge
|
|
src={staticBadgeUrl(baseUrl, 'color', color, color)}
|
|
alt={color}
|
|
/>
|
|
</Fragment>
|
|
))}
|
|
</p>
|
|
)
|
|
}
|
|
|
|
renderStyleExamples() {
|
|
const { baseUrl } = this.props
|
|
return (
|
|
<QueryParamTable>
|
|
<tbody>
|
|
{advertisedStyles.map(style => {
|
|
const snippet = `?style=${style}&logo=appveyor`
|
|
const badgeUrl = staticBadgeUrl(baseUrl, 'style', style, 'green', {
|
|
logo: 'appveyor',
|
|
style,
|
|
})
|
|
return (
|
|
<QueryParam
|
|
key={style}
|
|
snippet={snippet}
|
|
documentation={<Badge src={badgeUrl} alt={style} />}
|
|
/>
|
|
)
|
|
})}
|
|
</tbody>
|
|
</QueryParamTable>
|
|
)
|
|
}
|
|
|
|
static renderNamedLogos() {
|
|
const renderLogo = logo => <LogoName key={logo}>{logo}</LogoName>
|
|
const [first, ...rest] = logos
|
|
return [renderLogo(first)].concat(
|
|
rest.reduce((result, logo) => result.concat([', ', renderLogo(logo)]), [])
|
|
)
|
|
}
|
|
|
|
static renderStaticBadgeEscapingRules() {
|
|
return (
|
|
<EscapingRuleTable>
|
|
<tbody>
|
|
<EscapingConversion
|
|
key="dashes"
|
|
lhs={
|
|
<span>
|
|
Dashes <code>--</code>
|
|
</span>
|
|
}
|
|
rhs={
|
|
<span>
|
|
<code>-</code> Dash
|
|
</span>
|
|
}
|
|
/>
|
|
<EscapingConversion
|
|
key="underscores"
|
|
lhs={
|
|
<span>
|
|
Underscores <code>__</code>
|
|
</span>
|
|
}
|
|
rhs={
|
|
<span>
|
|
<code>_</code> Underscore
|
|
</span>
|
|
}
|
|
/>
|
|
<EscapingConversion
|
|
key="spaces"
|
|
lhs={
|
|
<span>
|
|
<code>_</code> or Space <code> </code>
|
|
</span>
|
|
}
|
|
rhs={
|
|
<span>
|
|
<code> </code> Space
|
|
</span>
|
|
}
|
|
/>
|
|
</tbody>
|
|
</EscapingRuleTable>
|
|
)
|
|
}
|
|
|
|
render() {
|
|
const { baseUrl } = this.props
|
|
return (
|
|
<section>
|
|
<H2 id="your-badge">Your Badge</H2>
|
|
|
|
<H3 id="static-badge">Static</H3>
|
|
<StaticBadgeMaker baseUrl={baseUrl} />
|
|
|
|
<VerticalSpace />
|
|
|
|
<p>
|
|
<Snippet
|
|
snippet={`${baseUrl}/badge/<SUBJECT>-<STATUS>-<COLOR>.svg`}
|
|
/>
|
|
</p>
|
|
{this.constructor.renderStaticBadgeEscapingRules()}
|
|
{this.renderColorExamples()}
|
|
|
|
<H3 id="dynamic-badge">Dynamic</H3>
|
|
|
|
<DynamicBadgeMaker baseUrl={baseUrl} />
|
|
|
|
<p>
|
|
<StyledCode>
|
|
{baseUrl}
|
|
/badge/dynamic/json.svg?url=<URL>&label=<LABEL>&query=<
|
|
<a
|
|
href="https://www.npmjs.com/package/jsonpath"
|
|
target="_BLANK"
|
|
title="JSONdata syntax"
|
|
>
|
|
$.DATA.SUBDATA
|
|
</a>
|
|
>&colorB=<COLOR>&prefix=<PREFIX>&suffix=<SUFFIX>
|
|
</StyledCode>
|
|
</p>
|
|
<p>
|
|
<StyledCode>
|
|
{baseUrl}
|
|
/badge/dynamic/xml.svg?url=<URL>&label=<LABEL>&query=<
|
|
<a
|
|
href="https://www.npmjs.com/package/xpath"
|
|
target="_BLANK"
|
|
title="XPath syntax"
|
|
>
|
|
//data/subdata
|
|
</a>
|
|
>&colorB=<COLOR>&prefix=<PREFIX>&suffix=<SUFFIX>
|
|
</StyledCode>
|
|
</p>
|
|
<p>
|
|
<StyledCode>
|
|
{baseUrl}
|
|
/badge/dynamic/yaml.svg?url=<URL>&label=<LABEL>&query=<
|
|
<a
|
|
href="https://www.npmjs.com/package/jsonpath"
|
|
target="_BLANK"
|
|
title="JSONdata syntax"
|
|
>
|
|
$.DATA.SUBDATA
|
|
</a>
|
|
>&colorB=<COLOR>&prefix=<PREFIX>&suffix=<SUFFIX>
|
|
</StyledCode>
|
|
</p>
|
|
|
|
<VerticalSpace />
|
|
|
|
<H2 id="styles">Styles</H2>
|
|
|
|
<p>
|
|
The following styles are available. Flat is the default. Examples are
|
|
shown with an optional logo:
|
|
</p>
|
|
{this.renderStyleExamples()}
|
|
|
|
<p>
|
|
Here are a few other parameters you can use: (connecting several with
|
|
"&" is possible)
|
|
</p>
|
|
<QueryParamTable>
|
|
<tbody>
|
|
<QueryParam
|
|
key="label"
|
|
snippet="?label=healthinesses"
|
|
documentation={
|
|
<span>
|
|
Override the default left-hand-side text (
|
|
<a href="https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding">
|
|
URL-Encoding
|
|
</a>
|
|
{} needed for spaces or special characters!)
|
|
</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="logo"
|
|
snippet="?logo=appveyor"
|
|
documentation={
|
|
<span>
|
|
Insert one of the named logos from (
|
|
{this.constructor.renderNamedLogos()}) or{' '}
|
|
<a href="https://simpleicons.org/" target="_BLANK">
|
|
simple-icons
|
|
</a>
|
|
</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="logoSvg"
|
|
snippet="?logo=data:image/png;base64,…"
|
|
documentation={
|
|
<span>Insert custom logo image (≥ 14px high)</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="logoColor"
|
|
snippet="?logoColor=violet"
|
|
documentation={
|
|
<span>
|
|
Set the color of the logo (hex, rgb, rgba, hsl, hsla and css
|
|
named colors supported)
|
|
</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="logoWidth"
|
|
snippet="?logoWidth=40"
|
|
documentation={
|
|
<span>Set the horizontal space to give to the logo</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="link"
|
|
snippet="?link=http://left&link=http://right"
|
|
documentation={
|
|
<span>
|
|
Specify what clicking on the left/right of a badge should do
|
|
(esp. for social badge style)
|
|
</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="colorA"
|
|
snippet="?colorA=abcdef"
|
|
documentation={
|
|
<span>
|
|
Set background of the left part (hex, rgb, rgba, hsl, hsla and
|
|
css named colors supported)
|
|
</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="colorB"
|
|
snippet="?colorB=fedcba"
|
|
documentation={
|
|
<span>
|
|
Set background of the right part (hex, rgb, rgba, hsl, hsla
|
|
and css named colors supported)
|
|
</span>
|
|
}
|
|
/>
|
|
<QueryParam
|
|
key="maxAge"
|
|
snippet="?maxAge=3600"
|
|
documentation={
|
|
<span>
|
|
Set the HTTP cache lifetime in secs (rules are applied to
|
|
infer a default value on a per-badge basis, any values
|
|
specified below the default will be ignored)
|
|
</span>
|
|
}
|
|
/>
|
|
</tbody>
|
|
</QueryParamTable>
|
|
|
|
<p>
|
|
We support <code>.svg</code>, <code>.json</code>, <code>.png</code>{' '}
|
|
and a few others, but use them responsibly.
|
|
</p>
|
|
</section>
|
|
)
|
|
}
|
|
}
|