From b80de8391563460f9f80c5befd4bf6bdedcff8b0 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 14:56:08 -0700 Subject: [PATCH 01/17] use just the ERB bits --- pages/css/components/toasts.md | 47 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/pages/css/components/toasts.md b/pages/css/components/toasts.md index c4759def7f..a8b343388f 100644 --- a/pages/css/components/toasts.md +++ b/pages/css/components/toasts.md @@ -14,12 +14,11 @@ Toasts are used to show live, time-sensitive feedback to users. To create a default toast, use `.Toast`. Always use the `info` icon for default messages. -```html title="Default toast" +```erb title="Default toast"
- - + <%= octicon "info" %> Toast message goes here
@@ -28,12 +27,11 @@ To create a default toast, use `.Toast`. Always use the `info` icon for default The Toast content is formattable. We recommend keeping your message under 140 characters. -```html title="Toast with long text" +```erb title="Toast with long text"
- - + <%= octicon "info" %> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et ma
@@ -46,12 +44,11 @@ Use the success, warning, and error modifiers to communicate different states. Always use the `check` octicon for success states. -```html title="Success toast" +```erb title="Success toast"
- - + <%= octicon "check" %> Success message goes here.
@@ -60,12 +57,11 @@ Always use the `check` octicon for success states. Always use the `alert` octicon for warning states. -```html title="Warning toast" +```erb title="Warning toast"
- - + <%= octicon "alert" %> Warning message goes here.
@@ -74,12 +70,11 @@ Always use the `alert` octicon for warning states. Always use the `stop` octicon for error states. -```html title="Error toast" +```erb title="Error toast"
- - + <%= octicon "stop" %> Error message goes here
@@ -90,16 +85,15 @@ Always use the `stop` octicon for error states. Use `.Toast-dismissButton` to allow a user to explicitly dismiss a Toast. -```html title="Toast with dismiss" +```erb title="Toast with dismiss"
- - + <%= octicon "info" %> This toast is dismissable.
@@ -109,12 +103,11 @@ Use `.Toast-dismissButton` to allow a user to explicitly dismiss a Toast. Include a link to allow users to take actions within a Toast. -```html title="Toast with link" +```erb title="Toast with link"
- - + <%= octicon "info" %> Toast message goes here Action.
@@ -125,12 +118,11 @@ Include a link to allow users to take actions within a Toast. The `Toast--animateIn` and `Toast--animateOut` modifier classes can be used to animate the toast in and out from the bottom. -```html title="Toast animating" +```erb title="Toast animating"
- - + <%= octicon "info" %> Toast message goes here.
@@ -158,13 +150,12 @@ Add the `Toast--spinner` modifier class on the `Toast-icon` `svg` to communicate Use the `position-fixed bottom-0` utility classes on a wrapper element to position Toasts at the **bottom left** of the viewport. -```html title="Toast animating" +```erb title="Toast animating"
- - + <%= octicon "info" %> Toast message goes here.
From 7aa05a9d04a9fb59f7dd7825d2584805cb097fc5 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 14:56:55 -0700 Subject: [PATCH 02/17] normalize double quotes --- pages/css/components/select-menu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/css/components/select-menu.md b/pages/css/components/select-menu.md index 11df97253a..87bd2c30cb 100644 --- a/pages/css/components/select-menu.md +++ b/pages/css/components/select-menu.md @@ -411,7 +411,7 @@ If loading content should be deferred, use the [``](https://gi
- <%= octicon('octoface', class: "anim-pulse", :height => 32) %> + <%= octicon("octoface", class: "anim-pulse", :height => 32) %>
From b82a3fc69f51da71ea57ece7cc6b41b604fe4a28 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 14:57:11 -0700 Subject: [PATCH 03/17] use ERB converts for octicon() and avatar_for() --- lib/erb-to-html.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++ lib/mdx-loader.js | 19 ++++++++++- 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 lib/erb-to-html.js diff --git a/lib/erb-to-html.js b/lib/erb-to-html.js new file mode 100644 index 0000000000..6c8519bca8 --- /dev/null +++ b/lib/erb-to-html.js @@ -0,0 +1,84 @@ +const visit = require('unist-util-visit') +const cache = new Map() + +module.exports = options => { + const convert = converter(options) + return tree => { + visit(tree, 'code', (node, parent, index) => { + const match = node.lang ? node.lang.match(/^[a-z]+/) : null + const lang = match ? match[0] : null + if (lang === 'erb' || lang === 'html') { + const erb = node.value + const html = convert(node.value) + + if (html && !html.includes('<%')) { + node.value = html + node.lang = node.lang.replace(/^erb/, 'html') + } + } else { + // console.warn(`Unknown code block lang: ${node.lang}`) + } + }) + } +} + +function converter({converters = {}}) { + return erb => { + const blocks = erb.match(/<%=[^%]+%>/g) + if (blocks && blocks.length) { + let html = erb + console.warn(`Replacing ${blocks.length} ERB block(s)...`) + for (const input of blocks) { + const output = convert(input) + if (output !== input) { + html = replaceAll(html, input, output) + } + } + return html + } + } + + function convert(block) { + if (cache.has(block)) { + return cache.get(block) + } + + const [_, method, argString] = block.match(/<%= *(\w+)[ \(]([^\)]+)\)? *%>/) + const parts = argString.split(/, */) + const args = [] + const kwargs = {} + for (const part of parts) { + let match + if (match = part.match(/^:(.+) => (.+)$/)) { + kwargs[unquote(match[1])] = unquote(match[2]) + } else if (match = part.match(/^(.+): (.+)$/)) { + kwargs[unquote(match[1])] = unquote(match[2]) + } else { + args.push(unquote(part)) + } + } + + if (typeof converters[method] === 'function') { + let output = converters[method](args, kwargs) + output = `\n${output}` + cache.set(block, output) + return output + } else { + console.warn(`Unable to convert: ${block}`) + return block + } + } +} + +function replaceAll(str, input, output) { + let result = str + while (result.includes(input)) { + result = result.replace(input, output) + } + return result +} + + +function unquote(str) { + return str.replace(/^\s*"([^"]+)"\s*$/, (_, value) => value) +} diff --git a/lib/mdx-loader.js b/lib/mdx-loader.js index 835c8434e1..7fa1f723a1 100644 --- a/lib/mdx-loader.js +++ b/lib/mdx-loader.js @@ -1,11 +1,13 @@ const {getOptions} = require('loader-utils') const mdx = require('@mdx-js/mdx') +const octicons = require('@primer/octicons') const emoji = require('remark-emoji') const images = require('remark-images') const rehypePrism = require('./rehype-prism') const textr = require('remark-textr') const toc = require('remark-toc') +const erbToHTML = require('./erb-to-html') const mdxExportJSONByDefault = require('mdx-constant') const grayMatter = require('gray-matter') @@ -22,7 +24,22 @@ module.exports = async function(source) { [toc, {heading: '(table of|section)? contents'}], images, emoji, - [textr, {plugins: [typographicBase]}] + [textr, {plugins: [typographicBase]}], + [erbToHTML, { + converters: { + octicon: ([icon], attrs) => { + if (octicons[icon]) { + return octicons[icon].toSVG(attrs) + } else { + throw new Error(`No such octicon: "${icon}"`) + } + }, + avatar_for: ([username, size], kwargs) => { + const attrs = Object.entries(kwargs).map(([key, value]) => ` ${key}="${value}"`).join(' ') + return `` + } + } + }] ], hastPlugins: [rehypePrism], compilers: [mdxExportJSONByDefault('frontMatter', data)] From c0571d6f95dc47254d3686f53ee51724a87bd27b Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 15:18:51 -0700 Subject: [PATCH 04/17] lint --- lib/erb-to-html.js | 13 +++++++------ lib/mdx-loader.js | 32 ++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/lib/erb-to-html.js b/lib/erb-to-html.js index 6c8519bca8..d5c24d6396 100644 --- a/lib/erb-to-html.js +++ b/lib/erb-to-html.js @@ -1,15 +1,16 @@ +/* eslint-disable no-console */ const visit = require('unist-util-visit') const cache = new Map() module.exports = options => { const convert = converter(options) return tree => { - visit(tree, 'code', (node, parent, index) => { + visit(tree, 'code', node => { const match = node.lang ? node.lang.match(/^[a-z]+/) : null const lang = match ? match[0] : null if (lang === 'erb' || lang === 'html') { const erb = node.value - const html = convert(node.value) + const html = convert(erb) if (html && !html.includes('<%')) { node.value = html @@ -43,15 +44,16 @@ function converter({converters = {}}) { return cache.get(block) } - const [_, method, argString] = block.match(/<%= *(\w+)[ \(]([^\)]+)\)? *%>/) + // eslint-disable-next-line no-unused-vars + const [_, method, argString] = block.match(/<%= *(\w+)[ (]([^)]+)\)? *%>/) const parts = argString.split(/, */) const args = [] const kwargs = {} for (const part of parts) { let match - if (match = part.match(/^:(.+) => (.+)$/)) { + if ((match = part.match(/^:(.+) => (.+)$/))) { kwargs[unquote(match[1])] = unquote(match[2]) - } else if (match = part.match(/^(.+): (.+)$/)) { + } else if ((match = part.match(/^(.+): (.+)$/))) { kwargs[unquote(match[1])] = unquote(match[2]) } else { args.push(unquote(part)) @@ -78,7 +80,6 @@ function replaceAll(str, input, output) { return result } - function unquote(str) { return str.replace(/^\s*"([^"]+)"\s*$/, (_, value) => value) } diff --git a/lib/mdx-loader.js b/lib/mdx-loader.js index 7fa1f723a1..4d076ff3ea 100644 --- a/lib/mdx-loader.js +++ b/lib/mdx-loader.js @@ -25,21 +25,29 @@ module.exports = async function(source) { images, emoji, [textr, {plugins: [typographicBase]}], - [erbToHTML, { - converters: { - octicon: ([icon], attrs) => { - if (octicons[icon]) { - return octicons[icon].toSVG(attrs) - } else { - throw new Error(`No such octicon: "${icon}"`) + [ + erbToHTML, + { + converters: { + /* eslint-disable camelcase, no-unused-vars */ + octicon: ([icon], attrs) => { + if (octicons[icon]) { + return octicons[icon].toSVG(attrs) + } else { + throw new Error(`No such octicon: "${icon}"`) + } + }, + avatar_for: ([username, size], kwargs) => { + const attrs = Object.entries(kwargs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(' ') + const s = size * 2 + return `` } - }, - avatar_for: ([username, size], kwargs) => { - const attrs = Object.entries(kwargs).map(([key, value]) => ` ${key}="${value}"`).join(' ') - return `` + /* eslint-enable */ } } - }] + ] ], hastPlugins: [rehypePrism], compilers: [mdxExportJSONByDefault('frontMatter', data)] From 2a716f99124dc41dd934a109ed62a6ece9874708 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 15:24:17 -0700 Subject: [PATCH 05/17] add @primer/octicons, bump stylelint-config-primer --- package-lock.json | 152 ++++++++++++++++++++-------------------------- package.json | 3 +- 2 files changed, 69 insertions(+), 86 deletions(-) diff --git a/package-lock.json b/package-lock.json index fcfe5e405e..0a0ecad832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1520,6 +1520,15 @@ } } }, + "@primer/octicons": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-9.1.1.tgz", + "integrity": "sha512-7EGM0+Kx39bIgaYr9bTCzFvBCxm+fqh/YJIoSns8zfCwss32ZJ2GDP3024UH709VQtM5cKFU4JcIYPHyGdSfIg==", + "dev": true, + "requires": { + "object-assign": "^4.1.1" + } + }, "@reach/router": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.2.1.tgz", @@ -5057,9 +5066,9 @@ "dev": true }, "caniuse-db": { - "version": "1.0.30000956", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000956.tgz", - "integrity": "sha512-qA9aAldTqeW+5HOQVIoTpYlHm4xLek9jA1Ch29ego7sZfI3gQdzZ/e4nV4eeYab2Qong6uTrydOBLaPhvYnzJA==", + "version": "1.0.30000985", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000985.tgz", + "integrity": "sha512-1m3CC9+dYNh/FHd0V1/McOB73CxjmzzrcXi360x8mKoApUY8QIOYXg4bU5QeJmlenn++20GBI38EKw6qQpJ3kQ==", "dev": true }, "caniuse-lite": { @@ -5973,6 +5982,12 @@ "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", "dev": true }, + "css-color-names": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", + "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=", + "dev": true + }, "css-loader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.0.tgz", @@ -9607,18 +9622,6 @@ } } }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -11946,9 +11949,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash-es": { @@ -11994,9 +11997,9 @@ "dev": true }, "lodash.mergewith": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true }, "lodash.pick": { @@ -12693,9 +12696,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -13566,6 +13569,18 @@ "which": "1" }, "dependencies": { + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -13582,13 +13597,13 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" } } @@ -17038,9 +17053,9 @@ "dev": true }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -18467,9 +18482,9 @@ } }, "stylelint-config-primer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-primer/-/stylelint-config-primer-7.0.0.tgz", - "integrity": "sha512-PpQTJK9WYEoPRIpQtshKeslcloxLwRWTrF+lLgWKxRNsD/J0xuW+ucykqHYeO5+fJALWgFS06MdKQD/eg0Iycw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-primer/-/stylelint-config-primer-7.0.1.tgz", + "integrity": "sha512-yuKUU/0Z490FOp4gEGOebdXOcc0T0Kx07qygXImNZp4xisTkDabSEFUxfj8SzLybe08pPyuTFoJeCD65jXExuQ==", "dev": true, "requires": { "stylelint-no-unsupported-browser-features": "^1.0.0", @@ -19025,22 +19040,6 @@ "sugarss": "^0.2.0", "svg-tags": "^1.0.0", "table": "^4.0.1" - }, - "dependencies": { - "table": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", - "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", - "dev": true, - "requires": { - "ajv": "^6.0.1", - "ajv-keywords": "^3.0.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - } } }, "sugarss": { @@ -19061,6 +19060,20 @@ "has-flag": "^1.0.0" } }, + "table": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "dev": true, + "requires": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", @@ -19278,14 +19291,6 @@ "dev": true, "requires": { "css-color-names": "0.0.3" - }, - "dependencies": { - "css-color-names": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", - "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=", - "dev": true - } } }, "system-components": { @@ -20183,38 +20188,15 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "uniq": { diff --git a/package.json b/package.json index d7fdb673a7..0e7bcf222e 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@primer/blueprints": "4.0.2", "@primer/components": "12.0.1", "@primer/next-pages": "0.0.3", + "@primer/octicons": "9.1.1", "@storybook/addon-viewport": "5.0.11", "@storybook/react": "5.0.11", "@svgr/webpack": "2.4.1", @@ -110,7 +111,7 @@ "style-loader": "^0.18.2", "styled-components": "4.1.2", "stylelint": "9.10.1", - "stylelint-config-primer": "7.0.0", + "stylelint-config-primer": "7.0.1", "table": "5.2.3", "tar": "4.4.8", "title-case": "^2.1.1", From d73daf52b3e8e1c32b37084e3093ec15e404abd7 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 16:43:45 -0700 Subject: [PATCH 06/17] be smarter in replaceAll() --- lib/erb-to-html.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/erb-to-html.js b/lib/erb-to-html.js index d5c24d6396..2776e59cac 100644 --- a/lib/erb-to-html.js +++ b/lib/erb-to-html.js @@ -49,8 +49,8 @@ function converter({converters = {}}) { const parts = argString.split(/, */) const args = [] const kwargs = {} + let match for (const part of parts) { - let match if ((match = part.match(/^:(.+) => (.+)$/))) { kwargs[unquote(match[1])] = unquote(match[2]) } else if ((match = part.match(/^(.+): (.+)$/))) { @@ -73,11 +73,7 @@ function converter({converters = {}}) { } function replaceAll(str, input, output) { - let result = str - while (result.includes(input)) { - result = result.replace(input, output) - } - return result + return str.split(input).join(output) } function unquote(str) { From 80829c15d28322abd9bf895fb756aa36cff5275e Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Mon, 22 Jul 2019 16:46:23 -0700 Subject: [PATCH 07/17] use real avatars --- lib/mdx-loader.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/mdx-loader.js b/lib/mdx-loader.js index 4d076ff3ea..4c48bc5e96 100644 --- a/lib/mdx-loader.js +++ b/lib/mdx-loader.js @@ -38,11 +38,12 @@ module.exports = async function(source) { } }, avatar_for: ([username, size], kwargs) => { + const name = username === 'current_user' ? 'github' : username const attrs = Object.entries(kwargs) .map(([key, value]) => ` ${key}="${value}"`) .join(' ') const s = size * 2 - return `` + return `` } /* eslint-enable */ } From 175f7da374dc53d4445fb0c58225a62d711c7cff Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 23 Jul 2019 10:00:49 -0700 Subject: [PATCH 08/17] tweak eslint disables --- lib/mdx-loader.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/mdx-loader.js b/lib/mdx-loader.js index 4c48bc5e96..ce3eba39d9 100644 --- a/lib/mdx-loader.js +++ b/lib/mdx-loader.js @@ -29,7 +29,6 @@ module.exports = async function(source) { erbToHTML, { converters: { - /* eslint-disable camelcase, no-unused-vars */ octicon: ([icon], attrs) => { if (octicons[icon]) { return octicons[icon].toSVG(attrs) @@ -37,6 +36,7 @@ module.exports = async function(source) { throw new Error(`No such octicon: "${icon}"`) } }, + // eslint-disable-next-line camelcase avatar_for: ([username, size], kwargs) => { const name = username === 'current_user' ? 'github' : username const attrs = Object.entries(kwargs) @@ -45,7 +45,6 @@ module.exports = async function(source) { const s = size * 2 return `` } - /* eslint-enable */ } } ] From 94a1963c9ee7715aa6953c58a588e9b677d06538 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 23 Jul 2019 10:42:23 -0700 Subject: [PATCH 09/17] fix ERB block rendering --- lib/erb-to-html.js | 36 +++++++++++++++++++++++------------- lib/mdx-loader.js | 2 +- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/erb-to-html.js b/lib/erb-to-html.js index 2776e59cac..c829f76d68 100644 --- a/lib/erb-to-html.js +++ b/lib/erb-to-html.js @@ -1,6 +1,7 @@ /* eslint-disable no-console */ const visit = require('unist-util-visit') const cache = new Map() +const ERB_BLOCK_PATTERN = /<%=[^%]+%>/g module.exports = options => { const convert = converter(options) @@ -11,28 +12,35 @@ module.exports = options => { if (lang === 'erb' || lang === 'html') { const erb = node.value const html = convert(erb) - - if (html && !html.includes('<%')) { + const remaining = html ? html.match(ERB_BLOCK_PATTERN) : null + if (html && !remaining) { node.value = html node.lang = node.lang.replace(/^erb/, 'html') + } else if (remaining) { + console.warn(`Unable to convert ${remaining.length} ERB blocks:\n ${remaining.join(' \n')}`) + } else { + // console.warn(`No conversions made in: ${erb}`) } } else { - // console.warn(`Unknown code block lang: ${node.lang}`) + console.warn(`Unknown code block lang: ${node.lang}`) } }) } } -function converter({converters = {}}) { +function converter({methods = {}}) { return erb => { - const blocks = erb.match(/<%=[^%]+%>/g) + const blocks = erb.match(ERB_BLOCK_PATTERN) if (blocks && blocks.length) { let html = erb console.warn(`Replacing ${blocks.length} ERB block(s)...`) - for (const input of blocks) { - const output = convert(input) - if (output !== input) { - html = replaceAll(html, input, output) + for (const block of blocks) { + const output = convert(block) + if (output !== block) { + const count = html.split(block).length - 1 + console.warn(` found ${count} instances of "${block}"`) + html = replaceAll(html, block, output) + console.warn(html) } } return html @@ -60,13 +68,15 @@ function converter({converters = {}}) { } } - if (typeof converters[method] === 'function') { - let output = converters[method](args, kwargs) - output = `\n${output}` + if (typeof methods[method] === 'function') { + let output = methods[method](args, kwargs) + console.warn(`converted: ${block} -> ${output}`) + const escaped = block.replace('<', '').replace('>', '') + output = `\n${output}` cache.set(block, output) return output } else { - console.warn(`Unable to convert: ${block}`) + console.warn(`No such ERB method implemented: "${method}"`) return block } } diff --git a/lib/mdx-loader.js b/lib/mdx-loader.js index ce3eba39d9..e7ee513f44 100644 --- a/lib/mdx-loader.js +++ b/lib/mdx-loader.js @@ -28,7 +28,7 @@ module.exports = async function(source) { [ erbToHTML, { - converters: { + methods: { octicon: ([icon], attrs) => { if (octicons[icon]) { return octicons[icon].toSVG(attrs) From 3a2077d385eece86e8056cd37539bcfe4c18de78 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 23 Jul 2019 10:42:47 -0700 Subject: [PATCH 10/17] import .octicon CSS from @primer/octicons --- pages/_app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/_app.js b/pages/_app.js index 8a5d4d9ace..ecd3fcfaf5 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -14,6 +14,7 @@ import {CONTENT_MAX_WIDTH} from '../docs/constants' import {repository} from '../package.json' import '../src/index.scss' +import '@primer/octicons/index.scss' const DocLink = props => const editLinkBase = `${repository}/edit/master/pages` From ee6f0c6740e4bbb922cafcd920f98ce01408ed84 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 23 Jul 2019 11:12:45 -0700 Subject: [PATCH 11/17] convert octicons "back" to ERB --- pages/css/components/select-menu.md | 62 +++++++++++++++++++---------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/pages/css/components/select-menu.md b/pages/css/components/select-menu.md index 87bd2c30cb..d80547abaa 100644 --- a/pages/css/components/select-menu.md +++ b/pages/css/components/select-menu.md @@ -13,7 +13,7 @@ The `SelectMenu` component provides advanced support for navigation, filtering, Use a `
` element to toggle the Select Menu. The `` element can be styled in many ways. In the example below it's a `.btn`. -```html +```erb
Choose an item @@ -22,7 +22,9 @@ Use a `
` element to toggle the Select Menu. The `` element can

Title

- +
@@ -43,7 +45,7 @@ Add a `.SelectMenu-header` to house a clear title and a close button. Note that In case the Select Menu should be aligned to the right, use `SelectMenu right-0`. -```html +```erb
@@ -54,7 +56,9 @@ In case the Select Menu should be aligned to the right, use `SelectMenu right-0`

Title

- +
@@ -75,7 +79,7 @@ In case the Select Menu should be aligned to the right, use `SelectMenu right-0` Add a `.SelectMenu-icon .octicon-check` icon and it will show up when `aria-checked="true"` is set. -```html +```erb
Choose an item @@ -84,7 +88,9 @@ Add a `.SelectMenu-icon .octicon-check` icon and it will show up when `aria-chec

Title

- +
+ + @@ -192,7 +202,7 @@ If the list is expected to get long, consider adding a `.SelectMenu-filter` inpu Also consider adding a `.SelectMenu-footer` at the bottom. It can be used for additional information, but can also greatly improve the scrolling performance because the list doesn't need to be repainted due to the rounded corners. -```html +```erb
Choose an item @@ -201,7 +211,9 @@ Also consider adding a `.SelectMenu-footer` at the bottom. It can be used for ad

Title

- +
@@ -246,7 +258,7 @@ Also consider adding a `.SelectMenu-footer` at the bottom. It can be used for ad Sometimes you need two or more lists of items in your Select Menu, e.g. branches and tags. Select Menu lists can be tabbed with the addition of `.SelectMenu-tabs` above the menu. -```html +```erb
Choose an item @@ -255,7 +267,9 @@ Sometimes you need two or more lists of items in your Select Menu, e.g. branches

Title

- +
@@ -289,7 +303,7 @@ Sometimes you need two or more lists of items in your Select Menu, e.g. branches A `SelectMenu-message` can be used to show different kind of messages to a user. Use utility classes to further style the message. -```html +```erb
Choose an item @@ -298,7 +312,9 @@ A `SelectMenu-message` can be used to show different kind of messages to a user.

Title

- +
@@ -318,7 +334,7 @@ A `SelectMenu-message` can be used to show different kind of messages to a user. When fetching large lists, consider showing a `.SelectMenu-loading` animation. -```html +```erb
Choose an item @@ -327,7 +343,9 @@ When fetching large lists, consider showing a `.SelectMenu-loading` animation.

Title

- +
@@ -350,7 +368,7 @@ When fetching large lists, consider showing a `.SelectMenu-loading` animation. Sometimes a Select Menu needs to communicate a "blank slate" where there's no content in the menu's list. Usually these include a clear call to action to add said content to the list. Swap out the contents of a `.SelectMenu-list` with a `.SelectMenu-blankslate` and customize its contents as needed. -```html +```erb
Choose an item @@ -359,7 +377,9 @@ Sometimes a Select Menu needs to communicate a "blank slate" where there's no co

Title

- +
@@ -392,7 +412,7 @@ When adding the `.SelectMenu` component on github.com, use the [``
My Select Menu
From f0b340a3cc1cd02706dcc0d2bdafd8ec008f2912 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Wed, 7 Aug 2019 13:41:08 -0700 Subject: [PATCH 12/17] import @primer/octicons/index.scss in core as requested by @jonrohan in #845 --- src/core/index.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/index.scss b/src/core/index.scss index f350b9ac66..f843bdbb7e 100644 --- a/src/core/index.scss +++ b/src/core/index.scss @@ -5,6 +5,9 @@ * Released under MIT license. Copyright (c) 2019 GitHub Inc. */ +// Include .octicon base styles +@import "@primer/octicons/index.scss"; + // Primer master file // // Imports all Primer files in their intended order for easy mass-inclusion. From f19944d21666f194bc8be89197f7f69fb9cf19b4 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Wed, 7 Aug 2019 13:56:46 -0700 Subject: [PATCH 13/17] move @primer/octicons into dependencies --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0e7bcf222e..5ffe5ee9db 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,9 @@ "test-urls": "node docs-test/urls.js", "test-migrate": "script/test-migrate" }, + "dependencies": { + "@primer/octicons": "9.1.1" + }, "devDependencies": { "@githubprimer/octicons-react": "^8.1.3", "@mdx-js/mdx": "^0.16.6", @@ -49,7 +52,6 @@ "@primer/blueprints": "4.0.2", "@primer/components": "12.0.1", "@primer/next-pages": "0.0.3", - "@primer/octicons": "9.1.1", "@storybook/addon-viewport": "5.0.11", "@storybook/react": "5.0.11", "@svgr/webpack": "2.4.1", From 7bb4b44f689afba0463e6cda6d2d26579759b298 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Wed, 7 Aug 2019 13:57:36 -0700 Subject: [PATCH 14/17] get loose with octicons dependency version --- package-lock.json | 4 +--- package.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a0ecad832..4c8eceec4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1524,7 +1524,6 @@ "version": "9.1.1", "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-9.1.1.tgz", "integrity": "sha512-7EGM0+Kx39bIgaYr9bTCzFvBCxm+fqh/YJIoSns8zfCwss32ZJ2GDP3024UH709VQtM5cKFU4JcIYPHyGdSfIg==", - "dev": true, "requires": { "object-assign": "^4.1.1" } @@ -13936,8 +13935,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", diff --git a/package.json b/package.json index 5ffe5ee9db..0aa562fc89 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "test-migrate": "script/test-migrate" }, "dependencies": { - "@primer/octicons": "9.1.1" + "@primer/octicons": "^9.1.1" }, "devDependencies": { "@githubprimer/octicons-react": "^8.1.3", From bc70747faaa0e96ae1cf9b492d031f0cf2e31149 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Wed, 7 Aug 2019 14:30:00 -0700 Subject: [PATCH 15/17] silence the ERB parser --- lib/erb-to-html.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/erb-to-html.js b/lib/erb-to-html.js index c829f76d68..3c42383920 100644 --- a/lib/erb-to-html.js +++ b/lib/erb-to-html.js @@ -17,12 +17,12 @@ module.exports = options => { node.value = html node.lang = node.lang.replace(/^erb/, 'html') } else if (remaining) { - console.warn(`Unable to convert ${remaining.length} ERB blocks:\n ${remaining.join(' \n')}`) + // console.warn(`Unable to convert ${remaining.length} ERB blocks:\n ${remaining.join(' \n')}`) } else { // console.warn(`No conversions made in: ${erb}`) } } else { - console.warn(`Unknown code block lang: ${node.lang}`) + // console.warn(`Unknown code block lang: ${node.lang}`) } }) } @@ -33,14 +33,14 @@ function converter({methods = {}}) { const blocks = erb.match(ERB_BLOCK_PATTERN) if (blocks && blocks.length) { let html = erb - console.warn(`Replacing ${blocks.length} ERB block(s)...`) + // console.warn(`Replacing ${blocks.length} ERB block(s)...`) for (const block of blocks) { const output = convert(block) if (output !== block) { const count = html.split(block).length - 1 - console.warn(` found ${count} instances of "${block}"`) + // console.warn(` found ${count} instances of "${block}"`) html = replaceAll(html, block, output) - console.warn(html) + // console.warn(html) } } return html From 069671fd61b291b2b81b8cea0a712683dd8ceef8 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Wed, 7 Aug 2019 14:30:14 -0700 Subject: [PATCH 16/17] convert remaining inline SVG examples back to ERB --- pages/css/components/navigation.md | 11 +++++----- pages/css/components/select-menu.md | 33 +++++++++++++++-------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/pages/css/components/navigation.md b/pages/css/components/navigation.md index 48b2f38f9b..cc27d03af1 100644 --- a/pages/css/components/navigation.md +++ b/pages/css/components/navigation.md @@ -195,11 +195,12 @@ Different kind of content can be added inside a Side Nav item. Use utility class With an avatar - + <%= octicon "octoface", class: "mr-2" %> With an icon - With a status icon + With a status icon + <%= octicon "primitive-dot", class: "color-green-5 ml-2 float-right" %> With a label label @@ -233,11 +234,11 @@ Or also appear nested, as a sub navigation. Use margin/padding utility classes t ```html diff --git a/pages/css/components/select-menu.md b/pages/css/components/select-menu.md index d80547abaa..f8f9721d9c 100644 --- a/pages/css/components/select-menu.md +++ b/pages/css/components/select-menu.md @@ -23,7 +23,7 @@ Use a `
` element to toggle the Select Menu. The `` element can

Title

@@ -57,7 +57,7 @@ In case the Select Menu should be aligned to the right, use `SelectMenu right-0`

Title

@@ -89,20 +89,20 @@ Add a `.SelectMenu-icon .octicon-check` icon and it will show up when `aria-chec

Title

@@ -130,7 +130,7 @@ The list of items is arguably the most important subcomponent within the menu. B

Title

@@ -142,7 +142,8 @@ The list of items is arguably the most important subcomponent within the menu. B With an avatar @@ -212,7 +213,7 @@ Also consider adding a `.SelectMenu-footer` at the bottom. It can be used for ad

Title

@@ -268,7 +269,7 @@ Sometimes you need two or more lists of items in your Select Menu, e.g. branches

Title

@@ -313,7 +314,7 @@ A `SelectMenu-message` can be used to show different kind of messages to a user.

Title

@@ -344,7 +345,7 @@ When fetching large lists, consider showing a `.SelectMenu-loading` animation.

Title

@@ -352,7 +353,7 @@ When fetching large lists, consider showing a `.SelectMenu-loading` animation.
- + <%= octicon "octoface", class: "anim-pulse", width: 32 %>
Loading...
@@ -378,12 +379,12 @@ Sometimes a Select Menu needs to communicate a "blank slate" where there's no co

Title

- + <%= octicon "repo", class: "color-gray-3", width: 24 %>

No repositories

We didn’t find any matching repositories that you can commit to.

From 6fca657e588bf5fcf6cfb7a64435374077b983e5 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Wed, 7 Aug 2019 14:39:09 -0700 Subject: [PATCH 17/17] lint --- lib/erb-to-html.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/erb-to-html.js b/lib/erb-to-html.js index 3c42383920..d6f159693b 100644 --- a/lib/erb-to-html.js +++ b/lib/erb-to-html.js @@ -37,7 +37,7 @@ function converter({methods = {}}) { for (const block of blocks) { const output = convert(block) if (output !== block) { - const count = html.split(block).length - 1 + // const count = html.split(block).length - 1 // console.warn(` found ${count} instances of "${block}"`) html = replaceAll(html, block, output) // console.warn(html)