From 05cf1c79a02e558fd0805a38aeb0478f09ebe3b2 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Thu, 22 Dec 2022 13:21:17 -0500 Subject: [PATCH 01/22] Introduce markdown lint --- .github/workflows/ci.yml | 3 + .markdownlint-cli2.cjs | 20 ++ package-lock.json | 382 ++++++++++++++++++++++++++++++++++++++- package.json | 3 + 4 files changed, 402 insertions(+), 6 deletions(-) create mode 100644 .markdownlint-cli2.cjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 906b360d03a..dfac06d07b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,9 @@ jobs: - name: Lint run: npm run lint + - name: Markdownlint + run: npm run markdownlint + test: strategy: fail-fast: false diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs new file mode 100644 index 00000000000..0d32503f993 --- /dev/null +++ b/.markdownlint-cli2.cjs @@ -0,0 +1,20 @@ +const githubMarkdownOpinions = require('@github/markdownlint-github') + +const options = githubMarkdownOpinions.init({ + // Disable rules we don't currently care to enforce pertaining to stylistic things. + 'line-length': false, + 'blanks-around-headings': false, + 'blanks-around-lists': false, + 'no-trailing-spaces': false, + 'no-multiple-blanks': false, + 'no-trailing-punctuation': false, + 'single-trailing-newline': false, + 'ul-indent': false, + 'no-hard-tabs': false, + 'first-line-heading': false +}) + +module.exports = { + config: options, + customRules: ['@github/markdownlint-github'] +} diff --git a/package-lock.json b/package-lock.json index a89b89b9a53..e35fc9db71e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,7 @@ "@babel/preset-typescript": "7.18.6", "@changesets/changelog-github": "0.4.7", "@changesets/cli": "2.25.1", + "@github/markdownlint-github": "^0.3.0", "@github/prettier-config": "0.0.6", "@playwright/test": "1.27.1", "@rollup/plugin-babel": "6.0.2", @@ -124,6 +125,7 @@ "lodash.isempty": "4.4.0", "lodash.isobject": "3.0.2", "lodash.keyby": "4.6.0", + "markdownlint-cli2": "^0.5.1", "prettier": "2.8.1", "react": "18.2.0", "react-dnd": "14.0.4", @@ -3032,6 +3034,15 @@ "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-2.1.1.tgz", "integrity": "sha512-J++rpd5H9baztabJQB82h26jtueOeBRSTqetk9Cri+Lj/s28ndu6Tovn0uHQaOKtBWDobFunk9b5pP5vcqt7cA==" }, + "node_modules/@github/markdownlint-github": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@github/markdownlint-github/-/markdownlint-github-0.3.0.tgz", + "integrity": "sha512-q35L9LA4trt/raFfOFt03UL2g1dsoimbdtIjspECvSx34KMS42FhKCGrBj0BazM5u4dbovHsAbtjzVQ7ZEWIEA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, "node_modules/@github/paste-markdown": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/@github/paste-markdown/-/paste-markdown-1.4.2.tgz", @@ -26080,9 +26091,9 @@ "dev": true }, "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -33597,6 +33608,15 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/lint-staged": { "version": "13.1.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", @@ -34245,6 +34265,40 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-table": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", @@ -34258,6 +34312,159 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/markdownlint": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "dev": true, + "dependencies": { + "markdown-it": "13.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.5.1.tgz", + "integrity": "sha512-f3Nb1GF/c8YSrV/FntsCWzpa5mLFJRlO+wzEgv+lkNQjU6MZflUwc2FbyEDPTo6oVhP2VyUOkK0GkFgfuktl1w==", + "dev": true, + "dependencies": { + "globby": "13.1.2", + "markdownlint": "0.26.2", + "markdownlint-cli2-formatter-default": "0.0.3", + "micromatch": "4.0.5", + "strip-json-comments": "5.0.0", + "yaml": "2.1.1" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2.js", + "markdownlint-cli2-config": "markdownlint-cli2-config.js", + "markdownlint-cli2-fix": "markdownlint-cli2-fix.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.3.tgz", + "integrity": "sha512-QEAJitT5eqX1SNboOD+SO/LNBpu4P4je8JlR02ug2cLQAqmIhh8IJnSK7AcaHBHhNADqdGydnPpQOpsNcEEqCw==", + "dev": true, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/markdownlint-cli2/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/markdownlint-cli2/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/markdownlint-cli2/node_modules/globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/markdownlint-cli2/node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/markdownlint-cli2/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/strip-json-comments": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", + "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/markdownlint-cli2/node_modules/yaml": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz", + "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -40946,6 +41153,12 @@ "node": ">=4.2.0" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "node_modules/uglify-js": { "version": "3.16.2", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz", @@ -44861,6 +45074,15 @@ "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-2.1.1.tgz", "integrity": "sha512-J++rpd5H9baztabJQB82h26jtueOeBRSTqetk9Cri+Lj/s28ndu6Tovn0uHQaOKtBWDobFunk9b5pP5vcqt7cA==" }, + "@github/markdownlint-github": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@github/markdownlint-github/-/markdownlint-github-0.3.0.tgz", + "integrity": "sha512-q35L9LA4trt/raFfOFt03UL2g1dsoimbdtIjspECvSx34KMS42FhKCGrBj0BazM5u4dbovHsAbtjzVQ7ZEWIEA==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, "@github/paste-markdown": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/@github/paste-markdown/-/paste-markdown-1.4.2.tgz", @@ -62312,9 +62534,9 @@ "dev": true }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { @@ -68043,6 +68265,15 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "lint-staged": { "version": "13.1.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", @@ -68547,6 +68778,33 @@ "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", "dev": true }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + } + } + }, "markdown-table": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", @@ -68556,6 +68814,112 @@ "repeat-string": "^1.0.0" } }, + "markdownlint": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "dev": true, + "requires": { + "markdown-it": "13.0.1" + } + }, + "markdownlint-cli2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.5.1.tgz", + "integrity": "sha512-f3Nb1GF/c8YSrV/FntsCWzpa5mLFJRlO+wzEgv+lkNQjU6MZflUwc2FbyEDPTo6oVhP2VyUOkK0GkFgfuktl1w==", + "dev": true, + "requires": { + "globby": "13.1.2", + "markdownlint": "0.26.2", + "markdownlint-cli2-formatter-default": "0.0.3", + "micromatch": "4.0.5", + "strip-json-comments": "5.0.0", + "yaml": "2.1.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + }, + "strip-json-comments": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", + "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "yaml": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz", + "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==", + "dev": true + } + } + }, + "markdownlint-cli2-formatter-default": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.3.tgz", + "integrity": "sha512-QEAJitT5eqX1SNboOD+SO/LNBpu4P4je8JlR02ug2cLQAqmIhh8IJnSK7AcaHBHhNADqdGydnPpQOpsNcEEqCw==", + "dev": true, + "requires": {} + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -73758,6 +74122,12 @@ "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "uglify-js": { "version": "3.16.2", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz", diff --git a/package.json b/package.json index ba94130efcb..772a64463f7 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "install:docs": "(cd docs && npm install --legacy-peer-deps)", "lint": "eslint '**/*.{js,ts,tsx,md,mdx}' --max-warnings=0", "lint:fix": "npm run lint -- --fix", + "markdownlint": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!node_modules\"", "test": "jest", "test:storybook": "test-storybook", "test:update": "npm run test -- --updateSnapshot", @@ -193,6 +194,8 @@ "jest-matchmedia-mock": "1.1.0", "jest-styled-components": "6.3.4", "jest-watch-typeahead": "2.1.1", + "@github/markdownlint-github": "^0.3.0", + "markdownlint-cli2": "^0.5.1", "jscodeshift": "0.13.0", "lint-staged": "13.1.0", "lodash.groupby": "4.6.0", From 9a0e81038765b4558e1425397e2bb58c71e7382c Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Wed, 28 Dec 2022 16:13:48 -0500 Subject: [PATCH 02/22] Add extension to devcontainer.json --- .devcontainer/devcontainer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cfc8d468ffb..445f947d4e8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,13 +1,13 @@ { "name": "Primer Components", "image": "mcr.microsoft.com/vscode/devcontainers/typescript-node:16", - "extensions": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"], + "extensions": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint", "DavidAnson.vscode-markdownlint"], "forwardPorts": [8000], "postCreateCommand": ["/bin/bash", "-c", "pushd docs && npm install && popd && npm install"], "remoteUser": "node", "features": { "ghcr.io/devcontainers/features/sshd:1": { - "version": "latest" + "version": "latest" } } } From 399abc16eb716e2b7c62f8df033832d9ce49a55b Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Wed, 28 Dec 2022 16:22:49 -0500 Subject: [PATCH 03/22] Organize rule configuration --- .markdownlint-cli2.cjs | 17 ++++--- package-lock.json | 112 +++++++++++++++++++++++++++++++++++++++++ package.json | 6 +-- 3 files changed, 126 insertions(+), 9 deletions(-) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 0d32503f993..9e20996a2b4 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -1,7 +1,12 @@ const githubMarkdownOpinions = require('@github/markdownlint-github') -const options = githubMarkdownOpinions.init({ - // Disable rules we don't currently care to enforce pertaining to stylistic things. +// Rules to enable +const rulesToEnable = { + 'no-duplicate-header': false, + 'ul-style': false, +} +// Rules we don't care to enforce. +const rulesToNotEnforce = { 'line-length': false, 'blanks-around-headings': false, 'blanks-around-lists': false, @@ -11,10 +16,10 @@ const options = githubMarkdownOpinions.init({ 'single-trailing-newline': false, 'ul-indent': false, 'no-hard-tabs': false, - 'first-line-heading': false -}) - + 'first-line-heading': false, +} +const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnable}) module.exports = { config: options, - customRules: ['@github/markdownlint-github'] + customRules: ['@github/markdownlint-github'], } diff --git a/package-lock.json b/package-lock.json index e35fc9db71e..4a2741ee218 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,6 +126,7 @@ "lodash.isobject": "3.0.2", "lodash.keyby": "4.6.0", "markdownlint-cli2": "^0.5.1", + "markdownlint-cli2-formatter-pretty": "0.0.3", "prettier": "2.8.1", "react": "18.2.0", "react-dnd": "14.0.4", @@ -34355,6 +34356,74 @@ "markdownlint-cli2": ">=0.0.4" } }, + "node_modules/markdownlint-cli2-formatter-pretty": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-pretty/-/markdownlint-cli2-formatter-pretty-0.0.3.tgz", + "integrity": "sha512-J+j4TwP/up97N7eEwq3vhhs5GNWENLaBGZZU+H2XodshOl9eQD8BYHOUq/8mN9t0nz7jFj79jQCBMgJvHL9rKQ==", + "dev": true, + "dependencies": { + "chalk": "5.0.0", + "terminal-link": "3.0.0" + }, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/markdownlint-cli2-formatter-pretty/node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2-formatter-pretty/node_modules/chalk": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.0.tgz", + "integrity": "sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/markdownlint-cli2-formatter-pretty/node_modules/terminal-link": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-3.0.0.tgz", + "integrity": "sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^5.0.0", + "supports-hyperlinks": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2-formatter-pretty/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/markdownlint-cli2/node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -68920,6 +68989,49 @@ "dev": true, "requires": {} }, + "markdownlint-cli2-formatter-pretty": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-pretty/-/markdownlint-cli2-formatter-pretty-0.0.3.tgz", + "integrity": "sha512-J+j4TwP/up97N7eEwq3vhhs5GNWENLaBGZZU+H2XodshOl9eQD8BYHOUq/8mN9t0nz7jFj79jQCBMgJvHL9rKQ==", + "dev": true, + "requires": { + "chalk": "5.0.0", + "terminal-link": "3.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "requires": { + "type-fest": "^1.0.2" + } + }, + "chalk": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.0.tgz", + "integrity": "sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==", + "dev": true + }, + "terminal-link": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-3.0.0.tgz", + "integrity": "sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg==", + "dev": true, + "requires": { + "ansi-escapes": "^5.0.0", + "supports-hyperlinks": "^2.2.0" + } + }, + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", diff --git a/package.json b/package.json index 772a64463f7..6e5d96103f4 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "install:docs": "(cd docs && npm install --legacy-peer-deps)", "lint": "eslint '**/*.{js,ts,tsx,md,mdx}' --max-warnings=0", "lint:fix": "npm run lint -- --fix", - "markdownlint": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!node_modules\"", + "markdownlint": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!node_modules\" \"!CHANGELOG.md\"", "test": "jest", "test:storybook": "test-storybook", "test:update": "npm run test -- --updateSnapshot", @@ -121,6 +121,7 @@ "@babel/preset-typescript": "7.18.6", "@changesets/changelog-github": "0.4.7", "@changesets/cli": "2.25.1", + "@github/markdownlint-github": "^0.3.0", "@github/prettier-config": "0.0.6", "@playwright/test": "1.27.1", "@rollup/plugin-babel": "6.0.2", @@ -194,14 +195,13 @@ "jest-matchmedia-mock": "1.1.0", "jest-styled-components": "6.3.4", "jest-watch-typeahead": "2.1.1", - "@github/markdownlint-github": "^0.3.0", - "markdownlint-cli2": "^0.5.1", "jscodeshift": "0.13.0", "lint-staged": "13.1.0", "lodash.groupby": "4.6.0", "lodash.isempty": "4.4.0", "lodash.isobject": "3.0.2", "lodash.keyby": "4.6.0", + "markdownlint-cli2": "^0.5.1", "prettier": "2.8.1", "react": "18.2.0", "react-dnd": "14.0.4", From 344c10444101880868bdc0df400985a5cd14feb4 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Wed, 28 Dec 2022 16:26:15 -0500 Subject: [PATCH 04/22] try introducing CI step --- .github/workflows/ci.yml | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfac06d07b7..7f6f686178d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ concurrency: cancel-in-progress: true jobs: - lint: + eslint: runs-on: ubuntu-latest steps: - name: Checkout repository @@ -26,10 +26,34 @@ jobs: - name: Lint run: npm run lint - - - name: Markdownlint - run: npm run markdownlint - + markdown: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Get specific changed files + id: changed-files + uses: tj-actions/changed-files@v34.5.0 + with: + files: | + **/*.md + **/*.mdx + files_ignore: | + .changeset/*.md + CHANGELOG.md + .node_modules/ + .github + - uses: xt0rted/markdownlint-problem-matcher@v2 + if: steps.changed-files.outputs.any_changed == 'true' + - uses: actions/setup-node@v3 + if: steps.changed-files.outputs.any_changed == 'true' + with: + node-version: 16 + cache: 'npm' + - name: Lint with Markdownlint + if: steps.changed-files.outputs.any_changed == 'true' + run: | + npm ci + npx markdownlint-cli2 ${{ steps.changed-files.outputs.all_changed_files }} test: strategy: fail-fast: false From 74eb62491830c4d4c468688a5cf386a7e6da18ec Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Thu, 29 Dec 2022 13:40:33 -0500 Subject: [PATCH 05/22] Configure formatter --- .markdownlint-cli2.cjs | 3 +++ package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 9e20996a2b4..5f143abd8e0 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -22,4 +22,7 @@ const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEna module.exports = { config: options, customRules: ['@github/markdownlint-github'], + outputFormatters: [ + ['markdownlint-cli2-formatter-pretty', {appendLink: true}], // ensures the error message includes a link to the rule documentation + ], } diff --git a/package.json b/package.json index 6e5d96103f4..e2f2aaedd3b 100644 --- a/package.json +++ b/package.json @@ -202,6 +202,7 @@ "lodash.isobject": "3.0.2", "lodash.keyby": "4.6.0", "markdownlint-cli2": "^0.5.1", + "markdownlint-cli2-formatter-pretty": "0.0.3", "prettier": "2.8.1", "react": "18.2.0", "react-dnd": "14.0.4", From 3b6eb97a8fbfe214dd856ec096b7fe8e15acbcf4 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Thu, 29 Dec 2022 13:42:07 -0500 Subject: [PATCH 06/22] Just add similar to eslint --- .github/workflows/ci.yml | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f6f686178d..ddeb906824b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,31 +29,19 @@ jobs: markdown: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Get specific changed files - id: changed-files - uses: tj-actions/changed-files@v34.5.0 - with: - files: | - **/*.md - **/*.mdx - files_ignore: | - .changeset/*.md - CHANGELOG.md - .node_modules/ - .github - - uses: xt0rted/markdownlint-problem-matcher@v2 - if: steps.changed-files.outputs.any_changed == 'true' - - uses: actions/setup-node@v3 - if: steps.changed-files.outputs.any_changed == 'true' + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 with: node-version: 16 - cache: 'npm' - - name: Lint with Markdownlint - if: steps.changed-files.outputs.any_changed == 'true' - run: | - npm ci - npx markdownlint-cli2 ${{ steps.changed-files.outputs.all_changed_files }} + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run markdownlint test: strategy: fail-fast: false From 18cc5c087f9e4497716755c18f76f52be8cbf743 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Thu, 29 Dec 2022 13:47:02 -0500 Subject: [PATCH 07/22] update config --- .markdownlint-cli2.cjs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 5f143abd8e0..80fc7ea20c5 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -1,10 +1,5 @@ const githubMarkdownOpinions = require('@github/markdownlint-github') -// Rules to enable -const rulesToEnable = { - 'no-duplicate-header': false, - 'ul-style': false, -} // Rules we don't care to enforce. const rulesToNotEnforce = { 'line-length': false, @@ -18,7 +13,7 @@ const rulesToNotEnforce = { 'no-hard-tabs': false, 'first-line-heading': false, } -const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnable}) +const options = githubMarkdownOpinions.init({...rulesToNotEnforce}) module.exports = { config: options, customRules: ['@github/markdownlint-github'], From 353150c4935053f55ffea03586a52886c03fe4c3 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:17:21 -0500 Subject: [PATCH 08/22] Fix: MD001/heading-increment/header-increment Heading levels should only increment by one level at a time --- .../adrs/adr-008-experimental-components.md | 11 ++-- contributor-docs/principles.md | 60 +++++++++---------- docs/content/FilterList.md | 4 +- docs/content/FilteredSearch.md | 2 +- docs/content/deprecated/Dropdown.md | 8 +-- 5 files changed, 41 insertions(+), 44 deletions(-) diff --git a/contributor-docs/adrs/adr-008-experimental-components.md b/contributor-docs/adrs/adr-008-experimental-components.md index 22545ec6acb..5cd95e51c87 100644 --- a/contributor-docs/adrs/adr-008-experimental-components.md +++ b/contributor-docs/adrs/adr-008-experimental-components.md @@ -8,7 +8,7 @@ Proposed ## Context -#### Recap: Drafts +### Recap: Drafts As we work on new components (or rewrites of old components), we often need to start with a "prototype"[^1] and not include them in the semantically versioned (semver-ed) main bundle. @@ -39,8 +39,6 @@ The approach that has served us well since Dec 2021 has been "drafts" (along wit We want to enable feature teams to contribute to Primer. We also want to make it clear which contributions haven't been evaluated by our high standards for Primer components. - -   ## Decision @@ -53,17 +51,16 @@ The approach that has served us well since Dec 2021 has been "drafts" (along wit This will help in sharing experimental components between the monolith and projects outside of monolith. The ownership and responsibility of maintenance will be shared by multiple teams (including primer). -#### Risks: +### Risks: This will require improvements in the development and publishing workflow for experimental components. Without making that investment, we could create more friction and make contributions more difficult. -   #### Other options considered -1. The code for experimental components should live in a new repository code `github.com/primer/react-candidates` to support different conventions and processes for experimental components and convey shared ownership between primer and product teams. - +1. The code for experimental components should live in a new repository code `github.com/primer/react-candidates` to support different conventions and processes for experimental components and convey shared ownership between primer and product teams. + Keeping experimental components in primer _org_ suggests that the primer _team_ would take up maintenance of these components while they are still candidates (bugs, a11y remedial, etc.). This will be a new parallel workstream for the team and with our current team size, we might not be able to give it the required attention. 2. The code for experimental components should live inside the monolith in [github/github/modules/react-shared](https://github.com/github/github/tree/master/app/assets/modules/react-shared) instead of a new repository. diff --git a/contributor-docs/principles.md b/contributor-docs/principles.md index d724e4029f0..bea7b74bb0c 100644 --- a/contributor-docs/principles.md +++ b/contributor-docs/principles.md @@ -1,39 +1,39 @@ # Principles -### Communication +## Communication Design systems provide a vocabulary between design and engineering, the language we use should be correct but not at the expense of providing clarity. Use words and descriptions that both designers and engineers can understand. -* Be a bridge not a barrier. Use vocabulary that provides meaning to both designers and engineers. -* Choose language that provides mutual understanding between engineering and design over specificity. -* Support new vocabulary with descriptions and examples. -* Be consistent in the application of vocabulary in written and verbal communication to reinforce understandings. -* Articulate what you are aiming to achieve as well as what you are not doing. +- Be a bridge not a barrier. Use vocabulary that provides meaning to both designers and engineers. +- Choose language that provides mutual understanding between engineering and design over specificity. +- Support new vocabulary with descriptions and examples. +- Be consistent in the application of vocabulary in written and verbal communication to reinforce understandings. +- Articulate what you are aiming to achieve as well as what you are not doing. -### Judgment +## Judgment There's often more than one way to do things, and there aren't always best-practice examples to follow. Despite this we still need to make decisions and keep moving forward. To deal with an uncertain future and still move forward we should have _strong opinions, weakly held_. -* Make decisions that move us forward rather than halting progress due to ambiguity or difference of opinion. -* Make decisions based on long term goals rather than this week's ship. -* Evaluate technology by the risk they present, not just the solution they offer. High risk deserves careful consideration, low risk deserves less attention. -* Have opinions and arguments for them, but remain open to seeing and hearing evidence that clashes with them when those opinions become wrong. -* Prioritize solutions for people who use the system and how it serves the customers who use products built with the system. -* Seek feedback on code review often, and more often when a solution takes you down a new path. -* Take time to provide good code review, encompassing the above values when providing feedback. - -### Innovation - -* Treat everything as an experiment. Make small incremental steps that provide proof towards goals, or disprove them. -* Ship often. We learn more from tangible outcomes than something that only lives as an idea. -* Work on reducing complexity and simplifying solutions to enable us to innovate faster. - -### Implementation - -* Engineer just enough of a solution, value declarative over abstraction. -* A little verbosity is better than clever code. Avoid implementations that reduce the ability for people to contribute. -* Automate and abstract when repetition is a hindrance. -* Seek feedback on implementations as often as possible. -* Everything is a component. -* Provide flexibility, but within the boundaries of the system. -* Assume that people will break the rules, and provide safe ways for them to do so. +- Make decisions that move us forward rather than halting progress due to ambiguity or difference of opinion. +- Make decisions based on long term goals rather than this week's ship. +- Evaluate technology by the risk they present, not just the solution they offer. High risk deserves careful consideration, low risk deserves less attention. +- Have opinions and arguments for them, but remain open to seeing and hearing evidence that clashes with them when those opinions become wrong. +- Prioritize solutions for people who use the system and how it serves the customers who use products built with the system. +- Seek feedback on code review often, and more often when a solution takes you down a new path. +- Take time to provide good code review, encompassing the above values when providing feedback. + +## Innovation + +- Treat everything as an experiment. Make small incremental steps that provide proof towards goals, or disprove them. +- Ship often. We learn more from tangible outcomes than something that only lives as an idea. +- Work on reducing complexity and simplifying solutions to enable us to innovate faster. + +## Implementation + +- Engineer just enough of a solution, value declarative over abstraction. +- A little verbosity is better than clever code. Avoid implementations that reduce the ability for people to contribute. +- Automate and abstract when repetition is a hindrance. +- Seek feedback on implementations as often as possible. +- Everything is a component. +- Provide flexibility, but within the boundaries of the system. +- Assume that people will break the rules, and provide safe ways for them to do so. diff --git a/docs/content/FilterList.md b/docs/content/FilterList.md index bb343f62f57..ee083325a3a 100644 --- a/docs/content/FilterList.md +++ b/docs/content/FilterList.md @@ -22,13 +22,13 @@ The FilterList component is a menu with filter options that filter the main cont ## Component props -#### FilterList +### FilterList | Name | Type | Default | Description | | :--- | :---------------- | :-----: | :----------------------------------- | | sx | SystemStyleObject | {} | Style to be applied to the component | -#### FilterList.Item +### FilterList.Item | Name | Type | Default | Description | | :------- | :---------------- | :-----: | :--------------------------------------------------------------- | diff --git a/docs/content/FilteredSearch.md b/docs/content/FilteredSearch.md index 6deee64a153..1ac2f8583d3 100644 --- a/docs/content/FilteredSearch.md +++ b/docs/content/FilteredSearch.md @@ -28,7 +28,7 @@ The FilteredSearch component helps style an ActionMenu and a TextInput side-by-s ## Component props -#### FilteredSearch.Children +### FilteredSearch.Children | Name | Type | Default | Description | | :------- | :---------------- | :-----: | :------------------------------------------------------------------------------------------------------------ | diff --git a/docs/content/deprecated/Dropdown.md b/docs/content/deprecated/Dropdown.md index f08fd426d2f..54ca06b1953 100644 --- a/docs/content/deprecated/Dropdown.md +++ b/docs/content/deprecated/Dropdown.md @@ -48,24 +48,24 @@ Dropdown.Menu wraps your menu content. Be sure to pass a `direction` prop to thi The Dropdown component is extended from the [`Details`](/Details) component and gets all props that the [`Details`](/Details) component gets. -#### Dropdown.Menu +### Dropdown.Menu | Name | Type | Default | Description | | :-------- | :---------------- | :-----: | :------------------------------------------------------------------------------------ | | direction | String | 'sw' | Sets the direction of the dropdown menu. Pick from 'ne', 'e', 'se', 's', 'sw', or 'w' | | sx | SystemStyleObject | {} | Style to be applied to the component | -#### Dropdown.Button +### Dropdown.Button See https://primer.style/react/Buttons#component-props -#### Dropdown.Caret +### Dropdown.Caret | Name | Type | Default | Description | | :--- | :---------------- | :-----: | :----------------------------------- | | sx | SystemStyleObject | {} | Style to be applied to the component | -#### Dropdown.Item +### Dropdown.Item | Name | Type | Default | Description | | :--- | :---------------- | :-----: | :----------------------------------- | From d2591ffcc2456511fd8e89f0e7f8bb381cdf5cc3 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:17:58 -0500 Subject: [PATCH 09/22] fix: MD030/list-marker-space Spaces after list markers --- contributor-docs/adrs/adr-005-box-sx.md | 76 ++++++++++++------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/contributor-docs/adrs/adr-005-box-sx.md b/contributor-docs/adrs/adr-005-box-sx.md index 4b0f81e55b8..8a5c483f093 100644 --- a/contributor-docs/adrs/adr-005-box-sx.md +++ b/contributor-docs/adrs/adr-005-box-sx.md @@ -10,44 +10,44 @@ In Primer React and consuming applications, we use many different patterns for c 1. Creating components with styled-components - ```tsx - const Avatar = styled.img.attrs(props => ({ - height: props.size, - width: props.size - }))` - display: inline-block; - overflow: hidden; - line-height: ${get('lineHeights.condensedUltra')}; - border-radius: ${props => getBorderRadius(props)}; - ${sx} - ` - ``` - - [Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0) - -2. Creating components with Box - - ```tsx - const Avatar: React.FC = ({size = 20, alt = '', square = false, sx = {}, ...props}) => { - const styles:BetterSystemStyleObject = { - display: 'inline-block', - overflow: 'hidden', - lineHeight: 'condensedUltra', - borderRadius: getBorderRadius({size, square}) - } - - return ( - (styles, sx)} // styles needs to merge with props.sx - {...props} - /> - ) - } - ``` - - [Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0) + ```tsx + const Avatar = styled.img.attrs(props => ({ + height: props.size, + width: props.size, + }))` + display: inline-block; + overflow: hidden; + line-height: ${get('lineHeights.condensedUltra')}; + border-radius: ${props => getBorderRadius(props)}; + ${sx} + ` + ``` + + [Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0) + +2. Creating components with Box + + ```tsx + const Avatar: React.FC = ({size = 20, alt = '', square = false, sx = {}, ...props}) => { + const styles: BetterSystemStyleObject = { + display: 'inline-block', + overflow: 'hidden', + lineHeight: 'condensedUltra', + borderRadius: getBorderRadius({size, square}), + } + + return ( + (styles, sx)} // styles needs to merge with props.sx + {...props} + /> + ) + } + ``` + + [Show full code example →](https://github.com/primer/react/pull/2019/files?diff=split&w=0)   From e92701d4249e1bc551eac4d8b31995a33c92b821 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:18:54 -0500 Subject: [PATCH 10/22] fix: MD040/fenced-code-language Fenced code blocks should have a language specified --- README.md | 4 ---- contributor-docs/CONTRIBUTING.md | 8 +------- migrating.md | 7 +++---- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f172d79424c..d441a04fb4d 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,3 @@ We love collaborating with folks inside and outside of GitHub and welcome contri ## New Component Proposals We welcome and encourage new component proposals from internal GitHub teams! Our best work comes from collaborating directly with the teams using Primer React Components in their projects. If you'd like to kick off a new component proposal, please submit an issue using the [component proposal issue template](https://github.com/primer/react/issues/new?template=new-component-proposal.md) and we will get in touch! - -[styled-components]: https://www.styled-components.com/docs -[primer css]: https://github.com/primer/primer -[flash of unstyled content]: https://en.wikipedia.org/wiki/Flash_of_unstyled_content diff --git a/contributor-docs/CONTRIBUTING.md b/contributor-docs/CONTRIBUTING.md index b9d6ddf3c67..15a30306fe2 100644 --- a/contributor-docs/CONTRIBUTING.md +++ b/contributor-docs/CONTRIBUTING.md @@ -85,7 +85,7 @@ const Component = styled.div` Component.defaultProps = { m: 0, - fontSize: 5 + fontSize: 5, } export default Component @@ -212,10 +212,4 @@ Make sure to run `npm install` from inside the `docs/` subfolder _as well as_ th Ensure you are using the latest minor of Node.js for the major version specified in the `.nvmrc` file. For example, if `.nvmrc` contains `8`, make sure you're using the latest version of Node.js with the major version of 8. -[classnames]: https://www.npmjs.com/package/classnames -[spread syntax]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax -[styled-system]: https://styled-system.com -[table]: https://jxnblk.com/styled-system/table -[npx]: https://www.npmjs.com/package/npx -[now]: https://zeit.co/now [primer.style]: https://primer.style diff --git a/migrating.md b/migrating.md index ef9ba0ba040..97d57ecef7c 100644 --- a/migrating.md +++ b/migrating.md @@ -102,7 +102,7 @@ There are two ways to change the theme of @primer/components components: const theme = { ...primer, space: [0, 8, 16, 32, 64], - fontSizes: [10, 12, 16, 24, 48] + fontSizes: [10, 12, 16, 24, 48], } // override @@ -126,8 +126,8 @@ There are two ways to change the theme of @primer/components components: const theme = { colors: { - magenta: '#f0f' - } + magenta: '#f0f', + }, } export default () => ( @@ -245,6 +245,5 @@ Beware that codemods are not 100% fool-proof and may break your code, especially [emotion]: https://emotion.sh [emotion-theming]: https://github.com/emotion-js/emotion/tree/master/packages/emotion-theming [styled-system]: http://jxnblk.com/styled-system/ -[themeget]: http://jxnblk.com/styled-system/api#themeget [primer css]: https://github.com/primer/primer [responsive values]: http://jxnblk.com/styled-system/responsive-styles#responsive-styles From 6675d931a7b75e0cbb36a6b6862cb627fc5b1d9f Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:21:56 -0500 Subject: [PATCH 11/22] Fix: MD051/link-fragments Link fragments should be valid --- migrating.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrating.md b/migrating.md index 97d57ecef7c..cfc1a49e2e4 100644 --- a/migrating.md +++ b/migrating.md @@ -9,7 +9,7 @@ - `UnderlineNavItem` is now `UnderlineNav.Item` - `FilterListItem` is now `FilterList.Item` -There is a [codemod](#codemods) available to upgrade component identifiers from [v3.x.x-beta](#3-0-0-beta): +There is a [codemod](#codemods) available to upgrade component identifiers from [v3.x.x-beta](#300-beta): ``` npx jscodeshift -t node_modules/@primer/components/codemods/v4.js path/to/src @@ -30,7 +30,7 @@ The following breaking changes must be accounted for manually: - The `Link` component no longer accepts `scheme` or `muted` props, and has no underline by default. - `DonutChart` is now simply `Donut`, and `DonutSlice` is `Donut.Slice`. -There is a [codemod](#codemods) available to upgrade from [2.x.x-beta](#2-0-0-beta) and updating the package name: +There is a [codemod](#codemods) available to upgrade from [2.x.x-beta](#200-beta) and updating the package name: ``` npx jscodeshift -t node_modules/@primer/components/codemods/v3.js path/to/src @@ -46,7 +46,7 @@ npx jscodeshift -t node_modules/@primer/components/codemods/v3.js path/to/src We suggest that you rename your components in the above order, since renaming `Block` to `Box` before renaming the old `Box` component to `BorderBox` will cause problems. -There is a [codemod](#codemods) available to upgrade from [1.x.x-beta](#1-0-0-beta): +There is a [codemod](#codemods) available to upgrade from [1.x.x-beta](#100-beta): ``` npx jscodeshift -t node_modules/primer-react/codemods/v2.js path/to/src From a7a29e32c1e273eeb52cee91ae1f5a3c500744c6 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:25:29 -0500 Subject: [PATCH 12/22] Create rules to enforce eventualy --- .markdownlint-cli2.cjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 80fc7ea20c5..57e6da75627 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -1,5 +1,9 @@ const githubMarkdownOpinions = require('@github/markdownlint-github') +// Rules we want to enforce +const rulesToEnforce = { + 'fenced-code-language': false, +} // Rules we don't care to enforce. const rulesToNotEnforce = { 'line-length': false, @@ -13,7 +17,7 @@ const rulesToNotEnforce = { 'no-hard-tabs': false, 'first-line-heading': false, } -const options = githubMarkdownOpinions.init({...rulesToNotEnforce}) +const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnforce}) module.exports = { config: options, customRules: ['@github/markdownlint-github'], From 88b2216632c6717f22e568a56cb3a927e0023913 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:29:15 -0500 Subject: [PATCH 13/22] Fix: no-emphasis-as-heading/no-emphasis-as-header Emphasis used instead of a heading --- docs/content/NavList.mdx | 4 ++-- docs/content/PageLayout.mdx | 6 +++--- docs/content/anchoredPosition.mdx | 4 ++-- docs/content/deprecated/ActionList.mdx | 26 ++++++++++++------------ docs/content/deprecated/ActionMenu.mdx | 18 ++++++++-------- docs/content/deprecated/BorderBox.md | 4 ++-- docs/content/deprecated/DropdownMenu.mdx | 14 ++++++------- docs/content/deprecated/Flex.md | 4 ++-- docs/content/deprecated/Grid.md | 4 ++-- docs/content/deprecated/Position.md | 4 ++-- docs/content/deprecated/SideNav.md | 4 ++-- docs/content/focusZone.mdx | 4 ++-- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/content/NavList.mdx b/docs/content/NavList.mdx index 642b680c7f8..6ccdf4fcf33 100644 --- a/docs/content/NavList.mdx +++ b/docs/content/NavList.mdx @@ -227,7 +227,7 @@ function App() { Summary @@ -351,6 +351,6 @@ function App() { stableApi: false, addressedApiFeedback: false, hasDesignGuidelines: false, - hasFigmaComponent: false + hasFigmaComponent: false, }} /> diff --git a/docs/content/PageLayout.mdx b/docs/content/PageLayout.mdx index 1b3f6ba2a72..37c1aa1a4f2 100644 --- a/docs/content/PageLayout.mdx +++ b/docs/content/PageLayout.mdx @@ -185,7 +185,7 @@ Add `offsetHeader` prop to specify the height of the custom sticky header along backgroundColor: 'canvas.subtle', borderBottom: '1px solid', borderColor: 'border.default', - zIndex: 1 + zIndex: 1, }} > Custom sticky header @@ -310,7 +310,7 @@ The `PageLayout` component uses [landmark roles](https://developer.mozilla.org/e Each component may be labeled through either `aria-label` or `aria-labelledby` in order to provide a unique label for the landmark. This can be helpful when there are multiple landmarks of the same type on the page. -**Links & Resources** +### Links & Resources - [W3C, Landmark roles](https://w3c.github.io/aria/#landmark_roles) - [WCAG, ARIA11 Technique](https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA11) @@ -688,6 +688,6 @@ On macOS, you can open the VoiceOver rotor by pressing `VO-U`. You can navigate stableApi: false, addressedApiFeedback: false, hasDesignGuidelines: false, - hasFigmaComponent: false + hasFigmaComponent: false, }} /> diff --git a/docs/content/anchoredPosition.mdx b/docs/content/anchoredPosition.mdx index 191d412dee7..c4fcff32a10 100644 --- a/docs/content/anchoredPosition.mdx +++ b/docs/content/anchoredPosition.mdx @@ -46,7 +46,7 @@ const settings = { side: 'outside-right', align: 'center', alignmentOffset: 10, - anchorOffset: -10 + anchorOffset: -10, } as Partial const float = document.getElementById('floatingElement') const anchor = document.getElementById('anchorElement') @@ -145,7 +145,7 @@ export const AnchoredPositionExample = () => { | settings | `AnchoredPositionHookSettings` | undefined | Optional settings to control how the anchored position is calculated. See below. | | dependencies | `React.DependencyList` | undefined | Dependencies to determine when to re-calculate the position. If undefined or `[]`, only calculate the position once. | -**Return value** +#### Return value | Name | Type | Description | | :----------------- | :---------------------------- | :------------------------------------------------- | diff --git a/docs/content/deprecated/ActionList.mdx b/docs/content/deprecated/ActionList.mdx index c25de07a382..13bfce59100 100644 --- a/docs/content/deprecated/ActionList.mdx +++ b/docs/content/deprecated/ActionList.mdx @@ -10,7 +10,7 @@ An `ActionList` is a list of items which can be activated or selected. `ActionLi Use [new version of ActionList](/ActionList) with composable API, design updates and accessibility fixes. -**Before** +### Before ```jsx ``` -**After** +### After ```jsx @@ -51,7 +51,7 @@ import {ActionList} from '@primer/react/deprecated' ActionList.Divider, {text: 'Copy link'}, {text: 'Edit file'}, - {text: 'Delete file', variant: 'danger'} + {text: 'Delete file', variant: 'danger'}, ]} /> ``` @@ -65,7 +65,7 @@ import {ActionList} from '@primer/react/deprecated' {groupId: '1', header: {title: 'Live query', variant: 'subtle'}}, {groupId: '2', header: {title: 'Layout', variant: 'subtle'}}, {groupId: '3'}, - {groupId: '4'} + {groupId: '4'}, ]} items={[ {key: '1', leadingVisual: TypographyIcon, text: 'Rename', groupId: '0', trailingVisual: '⌘R'}, @@ -77,7 +77,7 @@ import {ActionList} from '@primer/react/deprecated' text: 'Table', description: 'Information-dense table optimized for operations across teams', descriptionVariant: 'block', - groupId: '2' + groupId: '2', }, { key: '5', @@ -85,17 +85,17 @@ import {ActionList} from '@primer/react/deprecated' text: 'Board', description: 'Kanban-style board focused on visual states', descriptionVariant: 'block', - groupId: '2' + groupId: '2', }, { key: '6', leadingVisual: FilterIcon, text: 'Save sort and filters to current view', disabled: true, - groupId: '3' + groupId: '3', }, {key: '7', leadingVisual: FilterIcon, text: 'Save sort and filters to new view', groupId: '3'}, - {key: '8', leadingVisual: GearIcon, text: 'View settings', groupId: '4', trailingVisual: ArrowRightIcon} + {key: '8', leadingVisual: GearIcon, text: 'View settings', groupId: '4', trailingVisual: ArrowRightIcon}, ]} /> ``` @@ -107,11 +107,11 @@ import {ActionList} from '@primer/react/deprecated' items={[ { text: 'Vanilla link', - renderItem: props => + renderItem: props => , }, { text: 'React Router link', - renderItem: props => + renderItem: props => , }, { text: 'NextJS style', @@ -119,8 +119,8 @@ import {ActionList} from '@primer/react/deprecated' - ) - } + ), + }, ]} /> ``` diff --git a/docs/content/deprecated/ActionMenu.mdx b/docs/content/deprecated/ActionMenu.mdx index 967d91761c6..7f5821798d9 100644 --- a/docs/content/deprecated/ActionMenu.mdx +++ b/docs/content/deprecated/ActionMenu.mdx @@ -10,7 +10,7 @@ An `ActionMenu` is an ActionList-based component for creating a menu of actions Use [new version of ActionMenu](/ActionMenu) with composable API, design updates and accessibility fixes. -**Before** +### Before ```jsx ``` -**After** +### After ```jsx @@ -61,7 +61,7 @@ import {ActionMenu} from '@primer/react/deprecated' ActionMenu.Divider, {text: 'Copy link', key: 'copy-link'}, {text: 'Edit file', key: 'edit-file'}, - {text: 'Delete file', variant: 'danger', key: 'delete-file'} + {text: 'Delete file', variant: 'danger', key: 'delete-file'}, ]} /> ``` @@ -77,7 +77,7 @@ import {ActionMenu} from '@primer/react/deprecated' {groupId: '1', header: {title: 'Live query', variant: 'subtle'}}, {groupId: '2', header: {title: 'Layout', variant: 'subtle'}}, {groupId: '3'}, - {groupId: '4'} + {groupId: '4'}, ]} items={[ {key: '1', leadingVisual: TypographyIcon, text: 'Rename', groupId: '0'}, @@ -89,7 +89,7 @@ import {ActionMenu} from '@primer/react/deprecated' text: 'Table', description: 'Information-dense table optimized for operations across teams', descriptionVariant: 'block', - groupId: '2' + groupId: '2', }, { key: '5', @@ -97,17 +97,17 @@ import {ActionMenu} from '@primer/react/deprecated' text: 'Board', description: 'Kanban-style board focused on visual states', descriptionVariant: 'block', - groupId: '2' + groupId: '2', }, { key: '6', leadingVisual: FilterIcon, text: 'Save sort and filters to current view', disabled: true, - groupId: '3' + groupId: '3', }, {key: '7', leadingVisual: FilterIcon, text: 'Save sort and filters to new view', groupId: '3'}, - {key: '8', leadingVisual: GearIcon, text: 'View settings', groupId: '4'} + {key: '8', leadingVisual: GearIcon, text: 'View settings', groupId: '4'}, ]} /> ``` diff --git a/docs/content/deprecated/BorderBox.md b/docs/content/deprecated/BorderBox.md index 3a978b1c2e4..151a410d746 100644 --- a/docs/content/deprecated/BorderBox.md +++ b/docs/content/deprecated/BorderBox.md @@ -9,13 +9,13 @@ BorderBox is a Box component with a border. When no `borderColor` is present, th Use [Box](/Box) instead. -**Before** +### Before ```jsx deprecated Item 1 ``` -**After** +### After ```jsx deprecated diff --git a/docs/content/deprecated/DropdownMenu.mdx b/docs/content/deprecated/DropdownMenu.mdx index 7b03ceb72c5..bd4ba02bc67 100644 --- a/docs/content/deprecated/DropdownMenu.mdx +++ b/docs/content/deprecated/DropdownMenu.mdx @@ -9,7 +9,7 @@ A `DropdownMenu` provides an anchor (button by default) that will open a floatin Use [new version of ActionMenu](/ActionMenu#with-selection) with composable API, design updates and accessibility fixes. -**Before** +### Before ```jsx const fieldTypes = [ @@ -17,7 +17,7 @@ const fieldTypes = [ {key: 1, text: 'Number'}, {key: 3, text: 'Date'}, {key: 4, text: 'Single select'}, - {key: 5, text: 'Iteration'} + {key: 5, text: 'Iteration'}, ] const Example = () => { @@ -39,7 +39,7 @@ const Example = () => { } ``` -**After** +### After Instead of `DropdownMenu`, you can use the `ActionMenu` with `ActionList selectionVariant=single`, this will give menu items the correct semantics: @@ -49,7 +49,7 @@ const fieldTypes = [ {id: 1, text: 'Number'}, {id: 3, text: 'Date'}, {id: 4, text: 'Single select'}, - {id: 5, text: 'Iteration'} + {id: 5, text: 'Iteration'}, ] const Example = () => { @@ -71,7 +71,7 @@ const Example = () => { ))} - + , ) } ``` @@ -90,9 +90,9 @@ function DemoComponent() { () => [ {text: '🔵 Cyan', id: 5, key: 'cyan'}, {text: '🔴 Magenta', key: 'magenta'}, - {text: '🟡 Yellow', key: 'yellow'} + {text: '🟡 Yellow', key: 'yellow'}, ], - [] + [], ) const [selectedItem, setSelectedItem] = React.useState() diff --git a/docs/content/deprecated/Flex.md b/docs/content/deprecated/Flex.md index 631e973a3ef..a272f1ad12b 100644 --- a/docs/content/deprecated/Flex.md +++ b/docs/content/deprecated/Flex.md @@ -9,7 +9,7 @@ The `Flex` component behaves the same as the `Box` component except that it has Use [Box](/Box) instead. -**Before** +### Before ```jsx deprecated @@ -19,7 +19,7 @@ Use [Box](/Box) instead. ``` -**After** +### After ```jsx deprecated diff --git a/docs/content/deprecated/Grid.md b/docs/content/deprecated/Grid.md index 7f1d6810a3e..d01036e31c5 100644 --- a/docs/content/deprecated/Grid.md +++ b/docs/content/deprecated/Grid.md @@ -9,7 +9,7 @@ Grid is a component that exposes grid system props. See the [CSS Tricks Complete Use [Box](/Box) instead. -**Before** +### Before ```jsx deprecated @@ -22,7 +22,7 @@ Use [Box](/Box) instead. ``` -**After** +### After ```jsx deprecated diff --git a/docs/content/deprecated/Position.md b/docs/content/deprecated/Position.md index 8faae3c9475..6efa8d557af 100644 --- a/docs/content/deprecated/Position.md +++ b/docs/content/deprecated/Position.md @@ -9,7 +9,7 @@ The Position component is a wrapper component that gives the containing componen Use [Box](/Box) instead. -**Before** +### Before ```jsx deprecated <> @@ -21,7 +21,7 @@ Use [Box](/Box) instead. ``` -**After** +### After ```jsx deprecated <> diff --git a/docs/content/deprecated/SideNav.md b/docs/content/deprecated/SideNav.md index a2db1858682..4cf852fe97e 100644 --- a/docs/content/deprecated/SideNav.md +++ b/docs/content/deprecated/SideNav.md @@ -10,7 +10,7 @@ The Side Nav is a vertical list of navigational links, typically used on the lef Use [NavList](/NavList) instead. -**Before** +### Before ```jsx @@ -22,7 +22,7 @@ Use [NavList](/NavList) instead. ``` -**After** +### After ```jsx diff --git a/docs/content/focusZone.mdx b/docs/content/focusZone.mdx index 808a6a51dfc..661c44e4c60 100644 --- a/docs/content/focusZone.mdx +++ b/docs/content/focusZone.mdx @@ -59,7 +59,7 @@ Deploy Storybook to see live demos of `focusZone`. ```ts const settings = { - bindKeys: FocusKeys.ArrowVertical | FocusKeys.HomeAndEnd + bindKeys: FocusKeys.ArrowVertical | FocusKeys.HomeAndEnd, } as FocusZoneSettings const focusZone = document.getElementById('focusZoneContainer') focusZone(focusZone, settings) @@ -127,7 +127,7 @@ export const FocusZoneExample = () => { | settings | `FocusZoneHookSettings` | undefined | Optional settings to control how the focus zone behaves. See below. | | dependencies | `React.DependencyList` | undefined | Dependencies to determine when to initialize the focus zone. | -**Return value** +#### Return value | Name | Type | Description | | :------------------------- | :----------------------------- | :---------------------------------------------------------------------------------------- | From ad55a368f4a197ec8c08d2a222ff4e7121ab0374 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:30:40 -0500 Subject: [PATCH 14/22] fix: MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines --- docs/content/Textarea.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/Textarea.mdx b/docs/content/Textarea.mdx index 4491f504ff9..c8a85be80f1 100644 --- a/docs/content/Textarea.mdx +++ b/docs/content/Textarea.mdx @@ -187,6 +187,6 @@ By default, `Textarea` can be resized by the user vertically and horizontally. R stableApi: false, addressedApiFeedback: false, hasDesignGuidelines: false, - hasFigmaComponent: false + hasFigmaComponent: false, }} /> From f992a52a9538cb209f23fca99dce23f636a22a95 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:33:24 -0500 Subject: [PATCH 15/22] Disable stylistic rule --- .markdownlint-cli2.cjs | 1 + 1 file changed, 1 insertion(+) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 57e6da75627..28d2299eb57 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -16,6 +16,7 @@ const rulesToNotEnforce = { 'ul-indent': false, 'no-hard-tabs': false, 'first-line-heading': false, + 'no-space-in-emphasis': false, } const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnforce}) module.exports = { From c17e0e08a407b16b1fab449ead62ac04def14523 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:35:55 -0500 Subject: [PATCH 16/22] Add TODO --- .../adrs/adr-004-children-as-api.md | 21 ++-- .../component-contents-api-patterns.md | 118 ++++++++---------- 2 files changed, 62 insertions(+), 77 deletions(-) diff --git a/contributor-docs/adrs/adr-004-children-as-api.md b/contributor-docs/adrs/adr-004-children-as-api.md index 0dff7e8f0e8..39035b372a4 100644 --- a/contributor-docs/adrs/adr-004-children-as-api.md +++ b/contributor-docs/adrs/adr-004-children-as-api.md @@ -12,7 +12,6 @@ _Note: Consumer is used multiple times on this page. It refers to the developers ## Decision: - 1. Prefer using children for “content” 2. For composite components, the API should be decided by how much customisation is available for children. @@ -20,7 +19,9 @@ _Note: Consumer is used multiple times on this page. It refers to the developers For components that have design decisions baked in, should use strict props. For example, the color of the icon inside a Button component is decided by the `variant` prop on the Button. The API does not allow for changing that. ```jsx - + ``` On the other hand, if we want consumers to have more control over children, a composite API is the better choice. @@ -38,7 +39,7 @@ On the other hand, if we want consumers to have more control over children, a co With React, `children` is the out-of-the-box way for putting [phrasing content](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#phrasing_content) inside your component. By using `children` instead of our own custom prop, we can make the API “predictable” for its consumers. -image +image ```jsx // prefer this @@ -62,7 +63,7 @@ import {CheckIcon} from '@primer/octicons-react' render( Changes saved! - + , ) ``` @@ -149,8 +150,6 @@ When intentionally going off the happy path, developers can still drop down an a _Sidenote: We might want to name this prop `leadingIcon`, even if there is no `trailingIcon`. Consistent names across components plays a big role in making the API predictable._ - - ---
@@ -233,7 +232,7 @@ We use this pattern as well in `Button`, `Button.Counter` is a restricted versio image 8 -```jsx +````jsx @@ -259,7 +258,7 @@ For Example, [legacy ActionMenu](https://primer.style/react/deprecated/ActionMen ```jsx -``` +````
@@ -371,15 +370,13 @@ Prefer using children for “content” ``` @@ -393,10 +390,8 @@ But, we want to discourage customising the Icon’s color and size in the applic ``` - image 14 - We want to add a `Counter` that adapts to the variant without supporting all the props of a `CounterLabel` like `scheme`. `Button.Counter` is a restricted version of `CounterLabel`, making the right thing easy and wrong thing hard: diff --git a/contributor-docs/component-contents-api-patterns.md b/contributor-docs/component-contents-api-patterns.md index bb699416e4e..0844bc97d76 100644 --- a/contributor-docs/component-contents-api-patterns.md +++ b/contributor-docs/component-contents-api-patterns.md @@ -2,7 +2,7 @@ Consider a React component that renders a list of items. Here are two possible APIs that component might expose, both achieving an equivalent result. -### A: Contents passed as React children +### A: Contents passed as React children ```jsx @@ -19,11 +19,11 @@ Consider a React component that renders a list of items. Here are two possible A ```jsx ``` @@ -68,12 +68,12 @@ Though less common, sometimes the HTML schema puts tight restrictions on the kin Furthermore, for custom React components, there is a first-class approach for rendering your component's children: ```jsx -function MyFancyBox({ children }) { - return
{children}
; +function MyFancyBox({children}) { + return
{children}
} // usage -I have a blue border!; +;I have a blue border! ``` I call this "first class" because the JSX children that are defined between your component's opening and closing tags are wrapped up into a special prop called `children`. It is the component's responsibility to render those children in the appropriate spot. @@ -92,26 +92,22 @@ One _could_ imagine a parallel universe where a tooltip is achieved by some othe ```html ``` In custom React components, this pattern can be more common. In this example, the text to render is passed as a prop, as data rather than as pre-created React elements (i.e. JSX): ```jsx -function WordWrap({ text, charactersPerLine }) { - const lines = []; - for ( - let low = 0; - low + charactersPerLine < text.length; - low += charactersPerLine - ) { - lines.push(text.substr(low, charactersPerLine)); +function WordWrap({text, charactersPerLine}) { + const lines = [] + for (let low = 0; low + charactersPerLine < text.length; low += charactersPerLine) { + lines.push(text.substr(low, charactersPerLine)) } - const remaining = text.length % charactersPerLine; + const remaining = text.length % charactersPerLine if (remaining !== 0) { - lines.push(text.substr(text.length - remaining)); + lines.push(text.substr(text.length - remaining)) } return ( <> @@ -119,14 +115,11 @@ function WordWrap({ text, charactersPerLine }) {
{l}
))} - ); + ) } // usage -; +; ``` For further customization, one could imagine an optional `renderLine` prop that is used to give consumers control over the way a single line is rendered (see the section "Customization of content passed as data" below). @@ -144,18 +137,18 @@ Since both patterns are equally powerful, we should be able to write equivalent Let's start with `MyFancyBox`: ```jsx -function MyFancyBox({ contents }) { - const boxChildren = []; - if (typeof contents === "string" || React.isValidElement(contents)) { - boxChildren.push(contents); - } else if (typeof contents === "function") { - boxChildren.push(contents()); +function MyFancyBox({contents}) { + const boxChildren = [] + if (typeof contents === 'string' || React.isValidElement(contents)) { + boxChildren.push(contents) + } else if (typeof contents === 'function') { + boxChildren.push(contents()) } // implementation abbreviated for clarity - return
{boxChildren}
; + return
{boxChildren}
} // usage -; +; ``` This example is so esoteric that I think it's obvious which is superior. The original has a less-complex implementation and a clearer API (in the second, just looking at the usage example, there is no way to know that contents can also accept a React element or a function callback). @@ -165,25 +158,21 @@ This example is so esoteric that I think it's obvious which is superior. The ori Now let's dive into `WordWrap`, implemented with a React children-based API: ```jsx -function WordWrap({ children, charactersPerLine }) { - const items = React.Children.toArray(children); - let textContent = ""; +function WordWrap({children, charactersPerLine}) { + const items = React.Children.toArray(children) + let textContent = '' for (const child of items) { - if (typeof child === "string") { - textContent += child; + if (typeof child === 'string') { + textContent += child } } - const lines = []; - for ( - let low = 0; - low + charactersPerLine < textContent.length; - low += charactersPerLine - ) { - lines.push(textContent.substr(low, charactersPerLine)); + const lines = [] + for (let low = 0; low + charactersPerLine < textContent.length; low += charactersPerLine) { + lines.push(textContent.substr(low, charactersPerLine)) } - const remaining = textContent.length % charactersPerLine; + const remaining = textContent.length % charactersPerLine if (remaining !== 0) { - lines.push(textContent.substr(textContent.length - remaining)); + lines.push(textContent.substr(textContent.length - remaining)) } return ( <> @@ -191,13 +180,11 @@ function WordWrap({ children, charactersPerLine }) {
{l}
))} - ); + ) } // usage - - the quick brown fox jumps over the lazy dog -; +;the quick brown fox jumps over the lazy dog ``` Let's get the obvious out of the way: the component implementation is more complex. Instead of receiving the raw text as a prop, the component has to iterate through its children, figure out which ones are text nodes, and build up the string. @@ -225,12 +212,12 @@ I shall make the following claim: For example, take the following two implementations of a simple (contrived) List component: ```jsx -function List({ children, ordered }) { - const Elem = ordered ? "ol" : "ul"; - return {children}; +function List({children, ordered}) { + const Elem = ordered ? 'ol' : 'ul' + return {children} } -function Item({ children }) { - return
  • {children}
  • ; +function Item({children}) { + return
  • {children}
  • } // usage @@ -241,20 +228,20 @@ function MyApp() { Banana Cantaloupe
    - ); + ) } ``` ```jsx -function List({ items, ordered }) { - const Elem = ordered ? "ol" : "ul"; - const listItems = items.map((i) =>
  • i
  • ); - return {listItems}; +function List({items, ordered}) { + const Elem = ordered ? 'ol' : 'ul' + const listItems = items.map(i =>
  • i
  • ) + return {listItems} } // usage function MyApp() { - return ; + return } ``` @@ -265,6 +252,7 @@ Why do I bring this up? If you assume that the _owner_ of an element has the _hi I believe this is a reasonable assumption: an element owner should be able to expect that the element will be rendered as close to the definition as possible. Otherwise, this violates the principle of least surprise. ### The `React.Children` anti-pattern + Based on the above assumption, using `React.Children` can be an anti-pattern. `React.Children` allows a component to reach into elements that it does not own. In our `WordWrap` example that uses React children, it is clear that we do not respect the owner (as defined above) of these elements. We iterate through children, ignoring anything that is not a text node. With this reasoning, it's also easy to argue that `React.cloneElement` should be an anti-pattern. While that is true, there are ways to use `React.cloneElement` to simply augment children without altering their primary purpose or function. Adding additional props is a common use. @@ -275,7 +263,7 @@ While anti-patterns sometimes have their valid uses, those uses should be indivi One significant benefit to the contents as children pattern is the fact that it lends itself very naturally to customization. Since the parent owns the children, it can create whatever children it likes, deciding their props and element types. This level of customization can be achieved using the contents as data pattern too, but it's not quite as straightforward (for the component author or the component consumer). -One common practice is for a component to accept a "render prop." The render prop is a function that returns JSX (the same as a function component). That function should be passed any data that may be needed for rendering. Of course, components should ship with a default renderer and not rely on being passed a render prop. +One common practice is for a component to accept a "render prop." The render prop is a function that returns JSX (the same as a function component). That function should be passed any data that may be needed for rendering. Of course, components should ship with a default renderer and not rely on being passed a render prop. ## How to decide @@ -302,6 +290,7 @@ At this point we have shown that both patterns are valid, so how do we know whic Based on these observations, here are some guidelines to decide which type of API to build: ### When to use a data contract + - Data doesn't cleanly transfer to an element structure - Data needs to be manipulated before being converted to an element structure - Certain well-defined scenarios need to be supported @@ -310,7 +299,8 @@ Based on these observations, here are some guidelines to decide which type of AP - You are building a composite component ### When to use a children-based contract + - Your component doesn't care about the structure of children - Your component doesn't need to use `React.Children` - Your component is flexible enough to accommodate almost any child structure -- You are building an intermediate component that provides behaviors or styles to a container \ No newline at end of file +- You are building an intermediate component that provides behaviors or styles to a container From f39fa4d96040ac6faa5e5ada26ad9df6c4045303 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:37:19 -0500 Subject: [PATCH 17/22] Add note in config --- .markdownlint-cli2.cjs | 1 + 1 file changed, 1 insertion(+) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 28d2299eb57..1abeae622a8 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -3,6 +3,7 @@ const githubMarkdownOpinions = require('@github/markdownlint-github') // Rules we want to enforce const rulesToEnforce = { 'fenced-code-language': false, + 'no-duplicate-header': false, // Fix https://github.com/primer/doctocat/issues/527, then set this rule to `siblings_only: true` } // Rules we don't care to enforce. const rulesToNotEnforce = { From 433324fad1633a2c570b509f55f609e8a6d166aa Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:40:00 -0500 Subject: [PATCH 18/22] fix: GH002/no-generic-link-text Avoid using generic link text like or : --- README.md | 2 +- contributor-docs/testing.md | 2 +- docs/content/Details.md | 6 ++++-- docs/content/Overlay.mdx | 4 ++-- docs/content/primer-theme.md | 8 ++++---- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d441a04fb4d..241a92b6f85 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ yarn add @primer/react ## Roadmap -You can track our roadmap progress in the [Roadmap Project Board](https://github.com/primer/react/projects/3), see more detail in the [quarterly planning Discussions](https://github.com/primer/react/discussions?discussions_q=%5BRoadmap%5D), and find a list of all the current epic tracking issues [here](https://github.com/primer/react/discussions/997). +You can track our roadmap progress in the [Roadmap Project Board](https://github.com/primer/react/projects/3), see more detail in the [quarterly planning Discussions](https://github.com/primer/react/discussions?discussions_q=%5BRoadmap%5D), and find a [list of all the current epic tracking issues](https://github.com/primer/react/discussions/997). ## Contributing diff --git a/contributor-docs/testing.md b/contributor-docs/testing.md index 13e8570d3c8..1cad2114840 100644 --- a/contributor-docs/testing.md +++ b/contributor-docs/testing.md @@ -72,7 +72,7 @@ We predominantly use [@testing-library/react](https://testing-library.com/docs/r To make assertions about the elements we use [Jest](https://jestjs.io/) and [jest-dom](https://github.com/testing-library/jest-dom). -\*: You can read about the differences between `fireEvent` and `UserEvent` [here](https://testing-library.com/docs/user-event/intro/#differences-from-fireevent). +\*: Read about the [differences between `fireEvent` and `UserEvent`](https://testing-library.com/docs/user-event/intro/#differences-from-fireevent). ### Running Tests diff --git a/docs/content/Details.md b/docs/content/Details.md index 12b9577e37e..bf873621b71 100644 --- a/docs/content/Details.md +++ b/docs/content/Details.md @@ -4,7 +4,7 @@ title: Details status: Alpha --- -`Details` is a styled `details` element for use with the `useDetails` hook. The `useDetails` hook returns the `open` state, a `setOpen` function to manually change the open state, and **`getDetailsProps` which must be spread onto your `Details` element in order for `Details` to get receive the proper behaviors provided by the hook**. See Kent Dodd's article on this pattern [here](https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters). +`Details` is a styled `details` element for use with the `useDetails` hook. The `useDetails` hook returns the `open` state, a `setOpen` function to manually change the open state, and **`getDetailsProps` which must be spread onto your `Details` element in order for `Details` to get receive the proper behaviors provided by the hook**. See [Kent Dodd's article on this pattern](https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters). The `useDetails` hook also takes a few configuration options as parameters which are noted in the table below. @@ -52,7 +52,9 @@ You can also manually show/hide the content using the `setOpen` function returne
    Are you sure? - +
    ) }} diff --git a/docs/content/Overlay.mdx b/docs/content/Overlay.mdx index a1ad6ca2b36..8953a91e946 100644 --- a/docs/content/Overlay.mdx +++ b/docs/content/Overlay.mdx @@ -68,7 +68,7 @@ render() - The `Overlay` component has a `role="dialog"` set on it, if you are using `Overlay` for alerts, you can pass in `role="alertdialog"` instead. Please read the [W3C guidelines](https://www.w3.org/TR/wai-aria-1.1/#alertdialog) to determine which role is best for your use case - The `Overlay` component has `aria-modal` set to `true` by default and should not be overridden as all `Overlay`s behave as modals. -See the W3C accessibility recommendations for modals [here](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_roles_states_props). +See the [W3C accessibility recommendations for modals](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_roles_states_props). ## Positioning @@ -265,6 +265,6 @@ See the W3C accessibility recommendations for modals [here](https://www.w3.org/T stableApi: false, addressedApiFeedback: false, hasDesignGuidelines: false, - hasFigmaComponent: false + hasFigmaComponent: false, }} /> diff --git a/docs/content/primer-theme.md b/docs/content/primer-theme.md index 6c4db6aee57..4faa0bd1644 100644 --- a/docs/content/primer-theme.md +++ b/docs/content/primer-theme.md @@ -10,7 +10,7 @@ Many of our theme keys correspond to system props on our components. For example In the background, [styled-system](https://github.com/styled-system/styled-system) does the work of finding the `medium` value from `maxWidth` key in the theme file and applying the corresponding CSS. -Our full theme can be found [here](https://github.com/primer/react/blob/main/src/theme-preval.js). +Learn more about [our full theme](https://github.com/primer/react/blob/main/src/theme-preval.js). ### Custom Theming @@ -28,7 +28,7 @@ There are two ways to change the theme of Primer components: const theme = { ...primer, space: [0, 8, 16, 32, 64], - fontSizes: [10, 12, 16, 24, 48] + fontSizes: [10, 12, 16, 24, 48], } // override @@ -71,8 +71,8 @@ There are two ways to change the theme of Primer components: const theme = { colors: { - magenta: '#f0f' - } + magenta: '#f0f', + }, } export default () => ( From d7417235408a21268b4dcdab81c63ec870415c9b Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:43:38 -0500 Subject: [PATCH 19/22] update config --- .markdownlint-cli2.cjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 1abeae622a8..3af9a31b69a 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -1,11 +1,11 @@ const githubMarkdownOpinions = require('@github/markdownlint-github') -// Rules we want to enforce +// Rules we want to turn on but currently have too many violations const rulesToEnforce = { 'fenced-code-language': false, 'no-duplicate-header': false, // Fix https://github.com/primer/doctocat/issues/527, then set this rule to `siblings_only: true` } -// Rules we don't care to enforce. +// Rules we don't care to enforce (usually stylistic) const rulesToNotEnforce = { 'line-length': false, 'blanks-around-headings': false, @@ -18,6 +18,7 @@ const rulesToNotEnforce = { 'no-hard-tabs': false, 'first-line-heading': false, 'no-space-in-emphasis': false, + 'blanks-around-fences': false, } const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnforce}) module.exports = { From ef7242fba3cee49210e8754c8216a4bc3e334082 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Tue, 10 Jan 2023 10:56:09 -0500 Subject: [PATCH 20/22] Add exceptions for Link for generic text --- .markdownlint-cli2.cjs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index 3af9a31b69a..0fe41357310 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -20,7 +20,12 @@ const rulesToNotEnforce = { 'no-space-in-emphasis': false, 'blanks-around-fences': false, } -const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnforce}) + +const defaultOverrides = { + 'no-generic-link-text': {exceptions: ['link']}, // We don't want it to flag links that link to `Link` component. +} + +const options = githubMarkdownOpinions.init({...rulesToNotEnforce, ...rulesToEnforce, ...defaultOverrides}) module.exports = { config: options, customRules: ['@github/markdownlint-github'], From d1f87d2bf606e2dfb645b493aceb0cb1d8425608 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Wed, 11 Jan 2023 13:39:59 -0500 Subject: [PATCH 21/22] Update to @joshblack suggestion --- .github/workflows/ci.yml | 21 ++++----------------- package.json | 2 +- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ddeb906824b..f4cf765c256 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ concurrency: cancel-in-progress: true jobs: - eslint: + lint: runs-on: ubuntu-latest steps: - name: Checkout repository @@ -24,24 +24,11 @@ jobs: - name: Install dependencies run: npm ci - - name: Lint + - name: Lint JavaScript run: npm run lint - markdown: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 16 - - - name: Install dependencies - run: npm ci - - name: Lint - run: npm run markdownlint + - name: Lint markdown + run: npm run lint:md test: strategy: fail-fast: false diff --git a/package.json b/package.json index e2f2aaedd3b..2ad6881fca4 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "install:docs": "(cd docs && npm install --legacy-peer-deps)", "lint": "eslint '**/*.{js,ts,tsx,md,mdx}' --max-warnings=0", "lint:fix": "npm run lint -- --fix", - "markdownlint": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!node_modules\" \"!CHANGELOG.md\"", + "lint:md": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!node_modules\" \"!CHANGELOG.md\"", "test": "jest", "test:storybook": "test-storybook", "test:update": "npm run test -- --updateSnapshot", From 572c744a9b5cfbdba3f854597d7731680d9f97e2 Mon Sep 17 00:00:00 2001 From: Kate Higa Date: Wed, 11 Jan 2023 13:43:00 -0500 Subject: [PATCH 22/22] Update CONTRIBUTING.md --- contributor-docs/CONTRIBUTING.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contributor-docs/CONTRIBUTING.md b/contributor-docs/CONTRIBUTING.md index 15a30306fe2..e4e556fad16 100644 --- a/contributor-docs/CONTRIBUTING.md +++ b/contributor-docs/CONTRIBUTING.md @@ -109,6 +109,8 @@ const Component = styled.div` ### Linting +#### ESLint + We use the [React configuration](https://github.com/github/eslint-plugin-github/blob/master/lib/configs/react.js) from [GitHub's eslint plugin](https://github.com/github/eslint-plugin-github) to lint our JavaScript. To check your work before pushing, run: ```sh @@ -130,6 +132,14 @@ npm run lint -- --fix **Protip:** `npm run lint -- --quiet` (or `npx eslint --quiet ...`) will suppress warnings so that you can focus on fixing errors. +#### Markdownlint + +We use [markdownlint](https://github.com/markdownlint/markdownlint) to lint Markdown files, using [GitHub's markdownlint-github configuration](https://github.com/github/markdownlint-github). To check your work before pushing, run: + +```sh +npm run lint:md +``` + ### TypeScript support Primer React is written in TypeScript. We include type definitions in our built artifacts. To check types, run the `type-check` test script: