From 4d603c9ea51126c8c9a50116dc698413ca8ccb3d Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 11 Sep 2017 14:28:47 -0700 Subject: [PATCH 1/4] initial import of branch-name component --- modules/primer-branch-name/LICENSE | 21 +++++++ modules/primer-branch-name/README.md | 55 +++++++++++++++++++ modules/primer-branch-name/index.scss | 3 + .../primer-branch-name/lib/branch-name.scss | 1 + modules/primer-branch-name/package.json | 32 +++++++++++ modules/primer-css/package.json | 3 +- modules/primer-product/package.json | 3 +- 7 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 modules/primer-branch-name/LICENSE create mode 100644 modules/primer-branch-name/README.md create mode 100644 modules/primer-branch-name/index.scss create mode 100644 modules/primer-branch-name/lib/branch-name.scss create mode 100644 modules/primer-branch-name/package.json diff --git a/modules/primer-branch-name/LICENSE b/modules/primer-branch-name/LICENSE new file mode 100644 index 00000000..5715c136 --- /dev/null +++ b/modules/primer-branch-name/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/modules/primer-branch-name/README.md b/modules/primer-branch-name/README.md new file mode 100644 index 00000000..1fecf3e3 --- /dev/null +++ b/modules/primer-branch-name/README.md @@ -0,0 +1,55 @@ +# Primer CSS / Branch Name + +[![npm version](http://img.shields.io/npm/v/primer-branch-name.svg)](https://www.npmjs.org/package/primer-branch-name) +[![Build Status](https://travis-ci.org/primer/primer-css.svg?branch=master)](https://travis-ci.org/primer/primer-css) + +> A nice, consistent way to display branch names. + +This repository is a module of the full [primer-css][primer-css] repository. + +## Install + +This repository is distributed with [npm]. After [installing npm][install-npm], you can install `primer-branch-name` with this command. + +``` +$ npm install --save primer-branch-name +``` + +## Usage + +The source files included are written in [Sass][sass] (SCSS) You can simply point your sass `include-path` at your `node_modules` directory and import it like this. + +```scss +@import "primer-branch-name/index.scss"; +``` + +You can also import specific portions of the module by importing those partials from the `/lib/` folder. _Make sure you import any requirements along with the modules._ + +## Build + +For a compiled **CSS** version of this module, an npm script is included that will output a css version to `build/build.css` The built css file is also included in the npm package: + +``` +$ npm run build +``` + +## Documentation + + + +TODO: Write some documentation here. + + + +## License + +[MIT](./LICENSE) © [GitHub](https://github.com/) + +[primer-css]: https://github.com/primer/primer +[docs]: http://primercss.io/ +[npm]: https://www.npmjs.com/ +[install-npm]: https://docs.npmjs.com/getting-started/installing-node +[sass]: http://sass-lang.com/ diff --git a/modules/primer-branch-name/index.scss b/modules/primer-branch-name/index.scss new file mode 100644 index 00000000..d893139c --- /dev/null +++ b/modules/primer-branch-name/index.scss @@ -0,0 +1,3 @@ +// support files +@import "primer-support/index.scss"; +@import "./lib/branch-name.scss"; diff --git a/modules/primer-branch-name/lib/branch-name.scss b/modules/primer-branch-name/lib/branch-name.scss new file mode 100644 index 00000000..8034abe2 --- /dev/null +++ b/modules/primer-branch-name/lib/branch-name.scss @@ -0,0 +1 @@ +// SCSS goes here diff --git a/modules/primer-branch-name/package.json b/modules/primer-branch-name/package.json new file mode 100644 index 00000000..cae108a9 --- /dev/null +++ b/modules/primer-branch-name/package.json @@ -0,0 +1,32 @@ +{ + "version": "0.0.1", + "name": "primer-branch-name", + "description": "A nice, consistent way to display branch names.", + "homepage": "http://primercss.io/", + "primer": { + "category": "product", + "module_type": "components" + }, + "author": "GitHub, Inc.", + "license": "MIT", + "style": "index.scss", + "main": "build/index.js", + "repository": "https://github.com/primer/primer-css/tree/master/modules/primer-branch-name", + "bugs": { + "url": "https://github.com/primer/primer-css/issues" + }, + "scripts": { + "test-docs": "../../script/test-docs", + "build": "../../script/npm-run primer-module-build index.scss", + "prepare": "npm run build", + "lint": "../../script/lint-scss", + "test": "../../script/npm-run-all build lint test-docs" + }, + "dependencies": { + "primer-support": "4.3.0" + }, + "keywords": [ + "github", + "primer" + ] +} diff --git a/modules/primer-css/package.json b/modules/primer-css/package.json index 8a9fa3c4..427a0033 100644 --- a/modules/primer-css/package.json +++ b/modules/primer-css/package.json @@ -54,7 +54,8 @@ "primer-tables": "1.3.0", "primer-tooltips": "1.3.0", "primer-truncate": "1.3.0", - "primer-utilities": "4.6.0" + "primer-utilities": "4.6.0", + "primer-branch-name": "0.0.1" }, "keywords": [ "primer", diff --git a/modules/primer-product/package.json b/modules/primer-product/package.json index 827e79a0..7a1b05da 100644 --- a/modules/primer-product/package.json +++ b/modules/primer-product/package.json @@ -32,6 +32,7 @@ "primer-dropdown": "0.1.0", "primer-labels": "1.4.0", "primer-markdown": "3.6.0", - "primer-support": "4.3.0" + "primer-support": "4.3.0", + "primer-branch-name": "0.0.1" } } From 7a7222893a14f9c75371c6a51649eb827022d693 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 11 Sep 2017 15:48:20 -0700 Subject: [PATCH 2/4] clean up doc tests --- tests/modules/test-document-styles.js | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/modules/test-document-styles.js b/tests/modules/test-document-styles.js index d28fc9e0..d081c228 100644 --- a/tests/modules/test-document-styles.js +++ b/tests/modules/test-document-styles.js @@ -1,9 +1,11 @@ const test = require("ava") -const css = require(process.env.PWD) +const css = require(process.cwd()) const fs = require("fs") const glob = require("glob") -var selectors, classnames = null +let selectors +let classnames + const classRegex = /class="([^"]+)"/ig // Find unique selectors from the cssstats selector list @@ -11,7 +13,8 @@ function uniqueSelectors(s) { s = s.map(s => { // split multi-selectors into last class used .foo .bar .baz return s.split(" ").pop() - }).filter(s => { + }) + .filter(s => { // remove any selector that aren't just regular classnames eg. ::hover [type] return s.match(/^\.[a-z\-_]+$/ig) }) @@ -22,37 +25,37 @@ function uniqueSelectors(s) { // From the given glob sources array, read the files and return found classnames function documentedClassnames(sources) { - var cn = [] - sources.forEach( f => { - glob.sync(f).forEach( g => { + const classes = [] + sources.forEach(f => { + glob.sync(f).forEach(g => { var match = null // While we match a classRegex in the source while ((match = classRegex.exec(fs.readFileSync(g, "utf8"))) != null) { // Get the matched classnames "..." and split by space into classes - cn = cn.concat(match[1].split(" ")) + classes.push(...match[1].split(" ")) } }) }) // return only the unique classnames - return [...new Set(cn)] + return Array.from(new Set(classes)) } // Before all the tests get the selectors and classnames test.before(t => { selectors = uniqueSelectors(css.cssstats.selectors.values) classnames = documentedClassnames([ - 'docs/*.md', - 'README.md' + "docs/*.md", + "README.md" ]) }) test("Every selector class is documented", t => { - var undocumented = [] - selectors.forEach( selector => { - if (!classnames.includes(selector.replace(".", ""))) { + const undocumented = [] + selectors.forEach(selector => { + if (!classnames.includes(selector.replace(/^\./, ""))) { undocumented.push(selector) } }) From aac48253606157721d877e92c9cb5aff8c4927b4 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 11 Sep 2017 15:48:36 -0700 Subject: [PATCH 3/4] add branch-name SCSS and readme --- modules/primer-branch-name/README.md | 20 +++++++++++++++--- .../primer-branch-name/lib/branch-name.scss | 21 ++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/modules/primer-branch-name/README.md b/modules/primer-branch-name/README.md index 1fecf3e3..261e3924 100644 --- a/modules/primer-branch-name/README.md +++ b/modules/primer-branch-name/README.md @@ -36,11 +36,25 @@ $ npm run build ## Documentation -TODO: Write some documentation here. +Branch names can be a link name or not: + +```html +a_new_feature_branch +a_new_feature_branch +``` + +You may also include an octicon before the branch name text: + +```html + + <%= octicon("git-branch") width:16 height:16 %> + a_new_feature_branch + +``` diff --git a/modules/primer-branch-name/lib/branch-name.scss b/modules/primer-branch-name/lib/branch-name.scss index 8034abe2..f86ff604 100644 --- a/modules/primer-branch-name/lib/branch-name.scss +++ b/modules/primer-branch-name/lib/branch-name.scss @@ -1 +1,20 @@ -// SCSS goes here +// A nice way to display branch names inside the UI. Can be a link or not. +// stylelint-disable selector-max-type +.branch-name { + display: inline-block; + padding: 2px 6px; + font: 12px $mono-font; + color: rgba($black, 0.6); + background-color: lighten($blue-100, 3%); + border-radius: 3px; + + .octicon { + margin: 1px -2px 0 0; + color: desaturate($blue-300, 70%); + } +} + +// When a branch name is a link +// stylelint-disable selector-no-qualifying-type +a.branch-name { color: $text-blue; } +// stylelint-enable selector-no-qualifying-type From a1d8caef8503bf31f078a69643e7a6fd43685b7c Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 11 Sep 2017 15:58:49 -0700 Subject: [PATCH 4/4] treat ERB helpers as class name providers This adds a regex for documentation that essentially assumes ERB helpers like `<%= octicon("x") %>` will generate an element with the `octicon` class. cc @jonrohan --- tests/modules/test-document-styles.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/modules/test-document-styles.js b/tests/modules/test-document-styles.js index d081c228..89dc4367 100644 --- a/tests/modules/test-document-styles.js +++ b/tests/modules/test-document-styles.js @@ -6,7 +6,12 @@ const glob = require("glob") let selectors let classnames -const classRegex = /class="([^"]+)"/ig +const classPatterns = [ + // HTML class attributes + /class="([^"]+)"/ig, + // assume that ERB helpers generate an element with the same class + /<%= (\w+)\b/g, +] // Find unique selectors from the cssstats selector list function uniqueSelectors(s) { @@ -26,15 +31,20 @@ function uniqueSelectors(s) { // From the given glob sources array, read the files and return found classnames function documentedClassnames(sources) { const classes = [] - sources.forEach(f => { - glob.sync(f).forEach(g => { - var match = null + const files = sources.reduce((acc, pattern) => { + return acc.concat(glob.sync(pattern)) + }, []) - // While we match a classRegex in the source - while ((match = classRegex.exec(fs.readFileSync(g, "utf8"))) != null) { + files.forEach(file => { + let match = null + const content = fs.readFileSync(file, "utf8") - // Get the matched classnames "..." and split by space into classes - classes.push(...match[1].split(" ")) + classPatterns.forEach(pattern => { + // match each pattern against the source + while (match = pattern.exec(content)) { + // get the matched classnames and split by whitespace into classes + const klasses = match[1].trim().split(/\s+/) + classes.push(...klasses) } }) })