mirror of
https://github.com/primer/css.git
synced 2024-11-28 13:12:16 +03:00
commit
fadc008488
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,7 +4,7 @@
|
||||
.changelog
|
||||
.next/
|
||||
.sass-cache
|
||||
.storybuild/
|
||||
_site
|
||||
build/
|
||||
dist/
|
||||
node_modules/
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"env",
|
||||
"react",
|
||||
"minify"
|
||||
]
|
||||
}
|
13
.storybook/.eslintrc.json
Normal file
13
.storybook/.eslintrc.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": [
|
||||
"plugin:github/react"
|
||||
],
|
||||
"rules": {
|
||||
"import/no-namespace": 0
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import React from 'react'
|
||||
import {storiesOf} from '@storybook/react'
|
||||
import octicons from 'octicons'
|
||||
|
||||
export const Octicon = (props) => {
|
||||
const {name} = props
|
||||
if (name in octicons) {
|
||||
const svg = octicons[name].toSVG(props)
|
||||
return <span dangerouslySetInnerHTML={ {__html: svg } } />
|
||||
} else {
|
||||
throw new Error(`No such octicon: "${name}"!`)
|
||||
}
|
||||
}
|
||||
|
||||
const story = storiesOf('Octicons', module)
|
||||
|
||||
Object.keys(octicons).forEach(name => {
|
||||
story.add(name, () => {
|
||||
return (
|
||||
<div>
|
||||
<Octicon name={name} height="64" />
|
||||
<Octicon name={name} height="32" />
|
||||
<Octicon name={name} height="16" />
|
||||
</div>
|
||||
)
|
||||
})
|
||||
})
|
@ -1 +1 @@
|
||||
import '@storybook/addon-options/register'
|
||||
import '@storybook/addon-viewport/register'
|
||||
|
@ -1,29 +1,46 @@
|
||||
import React from 'react'
|
||||
import { configure, addDecorator } from '@storybook/react'
|
||||
import { setOptions } from '@storybook/addon-options'
|
||||
import '../modules/primer/index.scss'
|
||||
import { version } from '../modules/primer/package.json'
|
||||
import {configure, addParameters, addDecorator} from '@storybook/react'
|
||||
import {name, homepage, version} from '../package.json'
|
||||
import {INITIAL_VIEWPORTS} from '@storybook/addon-viewport'
|
||||
|
||||
setOptions({
|
||||
name: `Primer v${version}`,
|
||||
url: 'http://primer.github.io/',
|
||||
showDownPanel: false,
|
||||
// this enables HMR for the SCSS source files
|
||||
import '../src/index.scss'
|
||||
|
||||
// wrap every view in 4x padding
|
||||
addDecorator(story => <div className="p-4">{story()}</div>)
|
||||
|
||||
addParameters({
|
||||
options: {
|
||||
brandTitle: `${name}@${version}`,
|
||||
brandUrl: homepage,
|
||||
showAddonsPanel: false
|
||||
},
|
||||
viewport: {
|
||||
viewports: {
|
||||
sm: {
|
||||
name: 'Small ($width-sm)',
|
||||
styles: {width: '544px', height: 'auto'}
|
||||
},
|
||||
md: {
|
||||
name: 'Medium ($width-md)',
|
||||
styles: {width: '768px', height: 'auto'}
|
||||
},
|
||||
lg: {
|
||||
name: 'Large ($width-lg)',
|
||||
styles: {width: '1012px', height: 'auto'}
|
||||
},
|
||||
xl: {
|
||||
name: 'XL ($width-xl)',
|
||||
styles: {width: '1280px', height: 'auto'}
|
||||
},
|
||||
...INITIAL_VIEWPORTS
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
addDecorator(story => (
|
||||
<div className='p-4'>
|
||||
{story()}
|
||||
</div>
|
||||
))
|
||||
|
||||
const contexts = [
|
||||
require.context('../modules', true, /stories.*\.js$/),
|
||||
]
|
||||
|
||||
configure(() => {
|
||||
contexts.forEach(context => {
|
||||
context.keys()
|
||||
.filter(key => !key.includes('node_modules'))
|
||||
.forEach(context)
|
||||
})
|
||||
const loadMarkdown = require.context('../src', true, /\.md$/)
|
||||
for (const path of loadMarkdown.keys()) {
|
||||
loadMarkdown(path)
|
||||
}
|
||||
}, module)
|
||||
|
@ -1,27 +0,0 @@
|
||||
import parseCodeBlocks from 'code-blocks/lib/fromString'
|
||||
import htmlToReact from 'html-to-react'
|
||||
|
||||
const htmlParser = new htmlToReact.Parser()
|
||||
|
||||
const blockToStory = block => {
|
||||
return {
|
||||
title: block.title,
|
||||
story: () => htmlParser.parse(block.value),
|
||||
block,
|
||||
}
|
||||
}
|
||||
|
||||
export default function storiesFromMarkdown(req) {
|
||||
return req.keys().reduce((stories, file) => {
|
||||
const markdown = req(file)
|
||||
const path = file.replace(/^\.\//, '')
|
||||
const blocks = parseCodeBlocks(markdown, path)
|
||||
.filter(block => {
|
||||
// read: ```html *
|
||||
// skip: ```html * story="false"
|
||||
return block.lang === 'html' && block.info.story !== 'false'
|
||||
})
|
||||
.map(blockToStory)
|
||||
return stories.concat(blocks)
|
||||
}, [])
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// FIXME this should go away when we merge and release:
|
||||
// <https://github.com/primer/primer-module-build/pull/19>
|
||||
const plugins = require("primer-module-build/lib/.postcss.json")
|
||||
delete plugins.use
|
||||
|
||||
module.exports = {
|
||||
plugins,
|
||||
}
|
52
.storybook/story-loader.js
Normal file
52
.storybook/story-loader.js
Normal file
@ -0,0 +1,52 @@
|
||||
/* eslint-disable no-console */
|
||||
const {dirname} = require('path')
|
||||
const parseFromString = require('code-blocks/lib/fromString')
|
||||
|
||||
module.exports = function storyLoader(markdown) {
|
||||
// resourcePath is the full path ("/Users/probot/primer/css/...") to the file being parsed
|
||||
// rootContext is really just dirname(resourcePath)
|
||||
const {resourcePath = '', rootContext} = this
|
||||
|
||||
// the sourcePath option provides a way to collapse the
|
||||
// navigation hierarchy by trimming even more of the
|
||||
// resourcePath's prefix; if it's not provided, use the
|
||||
// rootContext
|
||||
const {sourcePath = rootContext} = this.query || {}
|
||||
|
||||
// strip the sourcePath from the beginning of the resourcePath
|
||||
const file = resourcePath.replace(`${sourcePath}/`, '')
|
||||
// finally, remove "/README" or "/docs" from the path,
|
||||
// then strip the ".md" filename extension
|
||||
const path = dirname(file)
|
||||
.replace(/(\/README|\/docs)/, '')
|
||||
.replace(/\.md$/, '')
|
||||
|
||||
const stories = storiesFromMarkdown(markdown, file)
|
||||
if (stories.length) {
|
||||
console.warn(`${stories.length} stories found in ${file}!`)
|
||||
return `
|
||||
const {storiesOf} = require('@storybook/react')
|
||||
const htmlToReact = require('html-to-react')
|
||||
|
||||
const chapter = storiesOf(${JSON.stringify(path)}, module)
|
||||
const stories = ${JSON.stringify(stories)}
|
||||
|
||||
const htmlParser = new htmlToReact.Parser()
|
||||
for (const {title, value} of stories) {
|
||||
chapter.add(title, () => htmlParser.parse(value))
|
||||
}
|
||||
`
|
||||
} else {
|
||||
return `module.exports = {markdown: ${JSON.stringify(markdown)}}`
|
||||
}
|
||||
}
|
||||
|
||||
function storiesFromMarkdown(markdown, file) {
|
||||
const path = file.replace(/^\.\//, '')
|
||||
return parseFromString(markdown, path).filter(block => {
|
||||
// yes: ```html
|
||||
// no: ```html dead
|
||||
// no: ```html inert
|
||||
return block.lang === 'html' && !block.info.dead && !block.info.inert
|
||||
})
|
||||
}
|
@ -1,29 +1,32 @@
|
||||
const path = require('path');
|
||||
const {resolve} = require('path')
|
||||
const sourcePath = resolve(__dirname, '../src')
|
||||
|
||||
const modulesPath = path.resolve(__dirname, '../modules')
|
||||
module.exports = ({config}) => {
|
||||
const babel = config.module.rules.find(rule => {
|
||||
return rule.test.test('test.js')
|
||||
}).use[0]
|
||||
|
||||
module.exports = (config, env) => {
|
||||
|
||||
if (env === 'PRODUCTION') {
|
||||
config.plugins = config.plugins
|
||||
.filter(plugin => plugin.constructor.name !== 'UglifyJsPlugin')
|
||||
}
|
||||
|
||||
const rules = config.module.rules
|
||||
|
||||
rules.forEach((rule, index) => {
|
||||
if ('README.md'.match(rule.test)) {
|
||||
// console.warn('replacing MD rule:', rule)
|
||||
rules.splice(index, 1, {
|
||||
test: /\.md$/,
|
||||
loader: 'raw-loader',
|
||||
})
|
||||
}
|
||||
config.module.rules = config.module.rules.filter(rule => {
|
||||
return !rule.test.test('test.md')
|
||||
})
|
||||
|
||||
rules.push(
|
||||
config.module.rules.push(
|
||||
{
|
||||
test: /\.md$/,
|
||||
include: sourcePath,
|
||||
loaders: [
|
||||
babel,
|
||||
{
|
||||
loader: require.resolve('./story-loader'),
|
||||
options: {
|
||||
sourcePath
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
include: sourcePath,
|
||||
loaders: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
@ -31,20 +34,11 @@ module.exports = (config, env) => {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
config: {
|
||||
path: require.resolve('./postcss.config.js'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
includePaths: [
|
||||
modulesPath,
|
||||
],
|
||||
path: require.resolve('../postcss.config.js')
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
include: modulesPath,
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
17
DEVELOP.md
17
DEVELOP.md
@ -96,23 +96,12 @@ Our Storybook setup allows you to view every HTML code block in Primer CSS's Mar
|
||||
npm run start-storybook
|
||||
```
|
||||
|
||||
Then visit http://localhost:8000 to test your work.
|
||||
This should open up the site in your browser (if not, navigate to `http://localhost:8001`).
|
||||
|
||||
### Code blocks
|
||||
All `html` fenced code blocks in `src/**/*.md` will be rendered as stories and listed under the relevant module's name in the left-hand nav. File changes should trigger a live reload automatically (after a brief delay).
|
||||
|
||||
If the bundle you're working on has a `stories.js`, it probably includes a snippet like this:
|
||||
|
||||
```js
|
||||
const stories = storiesOf('Module name', module)
|
||||
|
||||
storiesFromMarkdown(require.context('.', true, /\.md$/))
|
||||
.forEach(({title, story}) => {
|
||||
stories.add(title, story)
|
||||
})
|
||||
```
|
||||
|
||||
This is how we find all of the Markdown files in the bundle directory and generate stories from their code blocks. Storybook sections are labeled by the first argument to `storiesOf()` (in the above example, "Module name"), and individual stories get their titles from either the previous Markdown heading or the `title` attribute in the fenced code block. See the [`code-blocks` docs](https://npmjs.com/package/code-blocks) and the [`storiesFromMarkdown()` source](./.storybook/lib/storiesFromMarkdown.js) for more info.
|
||||
Note: At this time, we do not load any stories from `src/**/stories.js`.
|
||||
|
||||
## Scripts
|
||||
Our [`package.json`](package.json) houses a collection of [run-scripts] that we use to maintain, test, build, and publish Primer CSS, notably:
|
||||
@ -121,7 +110,7 @@ Our [`package.json`](package.json) houses a collection of [run-scripts] that we
|
||||
* `check-links` runs a link checker on your local development server (`localhost:3000`, started with `npm start`).
|
||||
* `lint` lints all of our SCSS source files.
|
||||
* `lint-js` lints the docs site and supporting scripts.
|
||||
* `now-build` and `now-start` are run on [Now] to build and start the docs site server.
|
||||
* `now-build` and `now-start` are run on [Now] to build and start the docs site server. `now-test` runs them both in order.
|
||||
* `sync` copies Markdown docs from `src/` to `pages/css/` and preps them for inclusion in the docs site.
|
||||
* `test-urls` compares a (pre-generated) list of paths from the [Primer Style Guide](https://styleguide.github.com/primer/) to files in `pages/css`, and lets us know if we've inadvertently deleted or renamed anything.
|
||||
* `test-migrate` tests the [`primer-migrate`](MIGRATING.md#primer-migrate) command line utility.
|
||||
|
@ -8,7 +8,7 @@ import Frame from './Frame'
|
||||
|
||||
import 'prism-github/prism-github.scss'
|
||||
|
||||
const LANG_PATTERN = /\blanguage-\.?(jsx?|html)\b/
|
||||
const LANG_PATTERN = /\blanguage-\.?(jsx|html)\b/
|
||||
|
||||
const converter = new HTMLtoJSX({
|
||||
indent: ' ',
|
||||
@ -23,9 +23,9 @@ const languageTransforms = {
|
||||
}
|
||||
|
||||
export default function CodeExample(props) {
|
||||
const {children, dangerouslySetInnerHTML, dead, source, ...rest} = props
|
||||
const {children, dangerouslySetInnerHTML, inert, source, ...rest} = props
|
||||
const lang = getLanguage(props.className)
|
||||
if (lang && !dead) {
|
||||
if (lang && !inert) {
|
||||
const liveProps = {
|
||||
code: source,
|
||||
scope: {Octicon, getIconByName},
|
||||
|
5410
package-lock.json
generated
5410
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@ -2,7 +2,7 @@
|
||||
"name": "@primer/css",
|
||||
"version": "12.1.1",
|
||||
"description": "Primer is the CSS framework that powers GitHub's front-end design. primer includes 23 packages that are grouped into 3 core meta-packages for easy install. Each package and meta-package is independently versioned and distributed via npm, so it's easy to include all or part of Primer within your own project.",
|
||||
"homepage": "http://primer.github.io/",
|
||||
"homepage": "https://primer.style/css",
|
||||
"author": "GitHub, Inc.",
|
||||
"license": "MIT",
|
||||
"style": "dist/primer.css",
|
||||
@ -24,21 +24,21 @@
|
||||
"scripts": {
|
||||
"fresh": "rm -rf node_modules; npm install",
|
||||
"dist": "script/dist",
|
||||
"build-storybook": "build-storybook -o build",
|
||||
"check-links": "script/check-links http://localhost:3000/css -v",
|
||||
"lint": "npm-run-all -s lint-css lint-js",
|
||||
"lint-css": "stylelint --quiet --syntax scss src/**/*.scss",
|
||||
"lint-js": "eslint lib docs",
|
||||
"lint-js": "eslint lib docs .storybook",
|
||||
"now-build": "next build",
|
||||
"now-start": "next start",
|
||||
"now-test": "npm-run-all -s now-build now-start",
|
||||
"postpublish": "script/postpublish",
|
||||
"prepare": "npm run dist",
|
||||
"prepublishOnly": "script/prepublish",
|
||||
"publish-storybook": "npm run storybook && gh-pages -d build -b gh-pages -r https://github.com/primer/storybook",
|
||||
"publish-storybook": "script/publish-storybook",
|
||||
"start": "next dev",
|
||||
"dev": "next dev",
|
||||
"start-storybook": "start-storybook -p 8000 -c .storybook",
|
||||
"start-storybook": "start-storybook -p 8001",
|
||||
"build-storybook": "build-storybook -o .storybuild",
|
||||
"test": "npm-run-all -s test-urls test-migrate",
|
||||
"test-all-modules": "ava --verbose tests/test-*.js",
|
||||
"test-urls": "node docs-test/urls.js",
|
||||
@ -49,9 +49,8 @@
|
||||
"@mdx-js/mdx": "^0.16.6",
|
||||
"@mdx-js/tag": "0.15.0",
|
||||
"@primer/components": "11.0.0",
|
||||
"@storybook/addon-options": "3.4.3",
|
||||
"@storybook/addons": "3.4.3",
|
||||
"@storybook/react": "3.4.3",
|
||||
"@storybook/addon-viewport": "5.0.0",
|
||||
"@storybook/react": "5.0.0",
|
||||
"@svgr/webpack": "2.4.1",
|
||||
"@zeit/next-css": "^1.0.1",
|
||||
"@zeit/next-sass": "^1.0.1",
|
||||
|
@ -43,7 +43,7 @@ As of [Primer v10.10.0](https://github.com/primer/css/releases/v10.10.0), `prime
|
||||
|
||||
Rather than toggling the `d-none` class in JavaScript, you should toggle the `hidden` property on an element. This means that you won't have to restore any more specific display utility (`d-inline` or `d-flex`, for instance) just to work around the order in which they're listed in the stylesheet.
|
||||
|
||||
```js dead
|
||||
```js
|
||||
// Good:
|
||||
element.hidden = !visible
|
||||
|
||||
|
@ -7,3 +7,7 @@ if [[ -f $file ]]; then
|
||||
cat $file | xargs rm -rfv
|
||||
rm $file
|
||||
fi
|
||||
|
||||
if [[ "$GITHUB_REF" = "refs/heads/master" ]]; then
|
||||
npm run publish-storybook
|
||||
fi
|
||||
|
@ -1,24 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const ghpages = require('gh-pages')
|
||||
const {GITHUB_ACTOR, GITHUB_TOKEN} = process.env
|
||||
|
||||
if (GITHUB_TOKEN) {
|
||||
console.error('Publish storybook: No GITHUB_TOKEN found for storybook publishing.')
|
||||
process.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
ghpages.publish('build', {
|
||||
branch: 'gh-pages',
|
||||
repo: `https://${GITHUB_ACTOR}:${process.env.GITHUB_TOKEN}@github.com/primer/storybook.git`,
|
||||
user: {
|
||||
name: 'Primer CSS',
|
||||
email: 'design-systems@github.com'
|
||||
}
|
||||
}, error => {
|
||||
if (error) {
|
||||
console.error('gh-pages failed to publish:', error.message.replace(process.env.GITHUB_TOKEN, '[secret]'))
|
||||
process.exitCode = 1
|
||||
}
|
||||
})
|
||||
#!/bin/bash
|
||||
remote=${STORYBOOK_GIT_URL:-https://github.com/primer/storybook}
|
||||
npm run build-storybook
|
||||
npx gh-pages -d .storybuild -b gh-pages -r "$remote" "$@"
|
||||
|
Loading…
Reference in New Issue
Block a user