From 344224fccdef2f3a37ed931c512e400b47301ea2 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Fri, 9 Jun 2023 18:40:23 +0100 Subject: [PATCH 01/20] Add width utility to limit line length for readability (#2410) * Add class to limit max-width to 65ch * Update layout.md with example of new class * Update layout.scss * Create .changeset/shy-cats-hug.md --------- Co-authored-by: simurai --- .changeset/shy-cats-hug.md | 5 +++++ docs/content/utilities/layout.md | 8 ++++++++ src/utilities/layout.scss | 10 ++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 .changeset/shy-cats-hug.md diff --git a/.changeset/shy-cats-hug.md b/.changeset/shy-cats-hug.md new file mode 100644 index 0000000000..50b8fee6a2 --- /dev/null +++ b/.changeset/shy-cats-hug.md @@ -0,0 +1,5 @@ +--- +"@primer/css": patch +--- + +Add width utility to limit line length for readability diff --git a/docs/content/utilities/layout.md b/docs/content/utilities/layout.md index d941802f69..be98f26a72 100644 --- a/docs/content/utilities/layout.md +++ b/docs/content/utilities/layout.md @@ -204,6 +204,14 @@ Use `.width-auto` to reset width to `auto` (initial value). Typically used with ``` +Use `.width-comfortable` to set width to `65ch`. This can be used on text elements to shorten the line length for better readability. + +```html live +

+ Bacon ipsum dolor amet meatball flank beef tail pig boudin ham hock chicken capicola. Shoulder ham spare ribs turducken pork tongue. Bresaola corned beef sausage jowl ribeye kielbasa tenderloin andouille leberkas tongue. Ribeye tri-tip tenderloin pig, chuck ground round chicken tongue corned beef biltong. +

+``` + Use `.height-fit` to set max-height 100%. ```html live diff --git a/src/utilities/layout.scss b/src/utilities/layout.scss index 6837b9a94c..7b6e963565 100644 --- a/src/utilities/layout.scss +++ b/src/utilities/layout.scss @@ -71,13 +71,15 @@ // Width and height utilities, helpful in combination // with display-table utilities and images /* Max width 100% */ -.width-fit { max-width: 100% !important; } +.width-fit { max-width: 100% !important; } /* Set the width to 100% */ -.width-full { width: 100% !important; } +.width-full { width: 100% !important; } +/* Set the max-width to 65 characters */ +.width-comfortable { max-width: 65ch !important; } /* Max height 100% */ -.height-fit { max-height: 100% !important; } +.height-fit { max-height: 100% !important; } /* Set the height to 100% */ -.height-full { height: 100% !important; } +.height-full { height: 100% !important; } /* Remove min-width from element */ .min-width-0 { min-width: 0 !important; } From 352ed7b75585c686c996a5e7c2c29e20e41d0672 Mon Sep 17 00:00:00 2001 From: Katie Langerman <18661030+langermank@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:13:04 -0700 Subject: [PATCH 02/20] Add new PostCSS fallback config (#2457) * add new fallback config * Create swift-moles-jump.md --- .changeset/swift-moles-jump.md | 5 +++++ package.json | 2 +- postcss.config.cjs | 29 +++++++++++++++++++++++++---- yarn.lock | 8 ++++---- 4 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 .changeset/swift-moles-jump.md diff --git a/.changeset/swift-moles-jump.md b/.changeset/swift-moles-jump.md new file mode 100644 index 0000000000..ea6cce305e --- /dev/null +++ b/.changeset/swift-moles-jump.md @@ -0,0 +1,5 @@ +--- +"@primer/css": patch +--- + +Add new PostCSS fallback config diff --git a/package.json b/package.json index 9d943a391c..51f4030ddd 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "storybook": "cd docs && yarn && yarn storybook" }, "dependencies": { - "@primer/primitives": "^7.11.10", + "@primer/primitives": "^7.11.12", "@primer/view-components": "^0.1.0" }, "devDependencies": { diff --git a/postcss.config.cjs b/postcss.config.cjs index a2eb2de8ae..17ff747390 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -3,7 +3,8 @@ const sass = require('@csstools/postcss-sass') const scss = require('postcss-scss') const scssImport = require('postcss-import') const { join } = require('path') -const importedJSONFromPrimitives = require('./node_modules/@primer/primitives/tokens-next-private/fallbacks/color-fallbacks.json') +const path = require('path') +const fs = require('fs') module.exports = { map: { @@ -20,9 +21,29 @@ module.exports = { }), autoprefixer, require('postcss-custom-properties-fallback')({ - importFrom: { - customProperties: importedJSONFromPrimitives - }, + importFrom: [ + () => { + const primitiveFallbacks = [ + 'color-fallbacks.json', + 'base/size/size.json', + 'base/typography/typography.json', + 'functional/size/border.json', + 'functional/size/breakpoints.json', + 'functional/size/size-coarse.json', + 'functional/size/size-fine.json', + 'functional/size/size.json', + 'functional/size/viewport.json', + 'functional/typography/typography.json', + ] + let customProperties = {} + for (const filePath of primitiveFallbacks) { + const fileData = fs.readFileSync(path.join(__dirname, './node_modules/@primer/primitives/tokens-next-private/fallbacks/', filePath), 'utf8') + customProperties = {...customProperties, ...JSON.parse(fileData)} + } + + return { customProperties: customProperties }; + } + ] }), ] } diff --git a/yarn.lock b/yarn.lock index fc0be236fb..626a64f682 100644 --- a/yarn.lock +++ b/yarn.lock @@ -960,10 +960,10 @@ resolved "https://registry.yarnpkg.com/@primer/behaviors/-/behaviors-1.3.4.tgz#04498185ad4504d85081d4288c74dc3f0e507c8b" integrity sha512-j6PhkDD1IdL9xrlKbUQ3YEM74B7Fgr1mIZJ6JaYJjM1Mvdutd/nBouM8SnwFZdBBbS+ZRfGhnx3plr833Pvf1Q== -"@primer/primitives@^7.11.10": - version "7.11.10" - resolved "https://registry.yarnpkg.com/@primer/primitives/-/primitives-7.11.10.tgz#9572358f1209dcd2ce3f1f0de12188dffae038e5" - integrity sha512-KwChxyp4qbLojZx5Nz8RUElM9K+ObzZWvzkYEu76TC4qEsqb9wW7n78jyov5WhUh5+qj2Qac1iCsPfeTQG5YBw== +"@primer/primitives@^7.11.12": + version "7.11.12" + resolved "https://registry.yarnpkg.com/@primer/primitives/-/primitives-7.11.12.tgz#1a36354e789f8cc3c178b66b2d100b64d4fb209d" + integrity sha512-AvTiuLHvvby2KPZbwwJ7GrtRJYgWyepF6XAOMw7G7Kc2iP3E32OHmaFukwh3gY+OqwcxY7st2tHWll2brk1vfQ== "@primer/stylelint-config@^12.4.0": version "12.7.0" From 2788008a183f262d55357ca6639336d805063382 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 11:43:12 +0900 Subject: [PATCH 03/20] Bump stylelint from 14.15.0 to 15.7.0 (#2459) Bumps [stylelint](https://github.com/stylelint/stylelint) from 14.15.0 to 15.7.0. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/14.15.0...15.7.0) --- updated-dependencies: - dependency-name: stylelint dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 116 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 93 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 51f4030ddd..952fda5af9 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "postcss-custom-properties-fallback": "^1.0.2", "prettier": "2.8.8", "semver": "7.3.8", - "stylelint": "14.15.0", + "stylelint": "15.7.0", "table": "6.8.1" }, "jest": { diff --git a/yarn.lock b/yarn.lock index 626a64f682..f98108be05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -523,6 +523,21 @@ human-id "^1.0.2" prettier "^2.7.1" +"@csstools/css-parser-algorithms@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.2.0.tgz#1268b07196d1118296443aeff41bca27d94b0981" + integrity sha512-9BoQ/jSrPq4vv3b9jjLW+PNNv56KlDH5JMx5yASSNrCtvq70FCNZUjXRvbCeR9hYj9ZyhURtqpU/RFIgg6kiOw== + +"@csstools/css-tokenizer@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz#07ae11a0a06365d7ec686549db7b729bc036528e" + integrity sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA== + +"@csstools/media-query-list-parser@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.0.tgz#6e1a5e12e0d103cd13b94bddb88b878bd6866103" + integrity sha512-MXkR+TeaS2q9IkpyO6jVCdtA/bfpABJxIrfkLswThFN8EZZgI2RfAHhm6sDNDuYV25d5+b8Lj1fpTccIcSLPsQ== + "@csstools/postcss-sass@5.0.1": version "5.0.1" resolved "https://registry.yarnpkg.com/@csstools/postcss-sass/-/postcss-sass-5.0.1.tgz#d5e67b4c81f1b634d722148fbe0e871b71b762a5" @@ -537,7 +552,7 @@ resolved "https://registry.yarnpkg.com/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz#32c3cdb2f7af3cd8f0dca357b592e7271f3831b5" integrity sha512-pH4KCsbtBLLe7eqUrw8brcuFO8IZlN36JjdKlOublibVdAIPHCzEnpBWOVUXK5sCf+DpBi8ZtuWtjF0srybdeA== -"@csstools/selector-specificity@^2.0.2": +"@csstools/selector-specificity@^2.0.2", "@csstools/selector-specificity@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== @@ -1779,6 +1794,16 @@ cosmiconfig@^7.1.0: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" + integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1854,6 +1879,14 @@ css-tokenize@^1.0.1: inherits "^2.0.1" readable-stream "^1.0.33" +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + css-url-regex@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-0.0.1.tgz#e05af8c6c290d451ef1632b455ea5c81b4b1395c" @@ -2965,7 +2998,7 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-tags@^3.2.0: +html-tags@^3.2.0, html-tags@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== @@ -2987,7 +3020,7 @@ iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ignore@^5.0.5, ignore@^5.2.0, ignore@^5.2.1: +ignore@^5.0.5, ignore@^5.2.0, ignore@^5.2.1, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -3852,6 +3885,11 @@ known-css-properties@^0.26.0: resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.26.0.tgz#008295115abddc045a9f4ed7e2a84dc8b3a77649" integrity sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg== +known-css-properties@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.27.0.tgz#82a9358dda5fe7f7bd12b5e7142c0a205393c0c5" + integrity sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg== + language-subtag-registry@~0.3.2: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" @@ -4028,6 +4066,11 @@ mathml-tag-names@^2.1.3: resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + meow@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.1.tgz#1ad64c4b76b2a24dfb2f635fddcadf320d251467" @@ -4501,10 +4544,10 @@ postcss-scss@^4.0.2: resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.6.tgz#5d62a574b950a6ae12f2aa89b60d63d9e4432bfd" integrity sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ== -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.9: - version "6.0.12" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz#2efae5ffab3c8bfb2b7fbf0c426e3bca616c4abb" - integrity sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg== +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.13, postcss-selector-parser@^6.0.9: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -4542,10 +4585,10 @@ postcss@8.4.5: picocolors "^1.0.0" source-map-js "^1.0.1" -postcss@^8.1.0, postcss@^8.1.4, postcss@^8.2.4, postcss@^8.3.11, postcss@^8.4.16, postcss@^8.4.19: - version "8.4.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab" - integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== +postcss@^8.1.0, postcss@^8.1.4, postcss@^8.2.4, postcss@^8.3.11, postcss@^8.4.16, postcss@^8.4.19, postcss@^8.4.24: + version "8.4.24" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" + integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" @@ -4909,6 +4952,11 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -5204,16 +5252,20 @@ stylelint-scss@^4.0.0: postcss-selector-parser "^6.0.11" postcss-value-parser "^4.2.0" -stylelint@14.15.0: - version "14.15.0" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.15.0.tgz#4df55078e734869f81f6b85bbec2d56a4b478ece" - integrity sha512-JOgDAo5QRsqiOZPZO+B9rKJvBm64S0xasbuRPAbPs6/vQDgDCnZLIiw6XcAS6GQKk9k1sBWR6rmH3Mfj8OknKg== +stylelint@15.7.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-15.7.0.tgz#945939a2ce9516998a198580e69b1ceef8a7c5f3" + integrity sha512-fQRwHwWuZsDn4ENyE9AsKkOkV9WlD2CmYiVDbdZPdS3iZh0ceypOn1EuwTNuZ8xTrHF+jVeIEzLtFFSlD/nJHg== dependencies: - "@csstools/selector-specificity" "^2.0.2" + "@csstools/css-parser-algorithms" "^2.2.0" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/media-query-list-parser" "^2.1.0" + "@csstools/selector-specificity" "^2.2.0" balanced-match "^2.0.0" colord "^2.9.3" - cosmiconfig "^7.1.0" + cosmiconfig "^8.2.0" css-functions-list "^3.1.0" + css-tree "^2.3.1" debug "^4.3.4" fast-glob "^3.2.12" fastest-levenshtein "^1.0.16" @@ -5221,32 +5273,32 @@ stylelint@14.15.0: global-modules "^2.0.0" globby "^11.1.0" globjoin "^0.1.4" - html-tags "^3.2.0" - ignore "^5.2.0" + html-tags "^3.3.1" + ignore "^5.2.4" import-lazy "^4.0.0" imurmurhash "^0.1.4" is-plain-object "^5.0.0" - known-css-properties "^0.26.0" + known-css-properties "^0.27.0" mathml-tag-names "^2.1.3" meow "^9.0.0" micromatch "^4.0.5" normalize-path "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.19" + postcss "^8.4.24" postcss-media-query-parser "^0.2.3" postcss-resolve-nested-selector "^0.1.1" postcss-safe-parser "^6.0.0" - postcss-selector-parser "^6.0.10" + postcss-selector-parser "^6.0.13" postcss-value-parser "^4.2.0" resolve-from "^5.0.0" string-width "^4.2.3" strip-ansi "^6.0.1" style-search "^0.1.0" - supports-hyperlinks "^2.3.0" + supports-hyperlinks "^3.0.0" svg-tags "^1.0.0" table "^6.8.1" v8-compile-cache "^2.3.0" - write-file-atomic "^4.0.2" + write-file-atomic "^5.0.1" stylelint@^14.8.0: version "14.16.1" @@ -5321,6 +5373,14 @@ supports-hyperlinks@^2.3.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-hyperlinks@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz#c711352a5c89070779b4dad54c05a2f14b15c94b" + integrity sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -5705,6 +5765,14 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" +write-file-atomic@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^4.0.1" + "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" From abc8965913313bbb969db9e1148fb5add9327ec9 Mon Sep 17 00:00:00 2001 From: Katie Langerman <18661030+langermank@users.noreply.github.com> Date: Tue, 13 Jun 2023 08:04:42 -0700 Subject: [PATCH 04/20] Add default `::selection` color (#2461) * add color * Create happy-brooms-lick.md --- .changeset/happy-brooms-lick.md | 5 +++++ src/base/base.scss | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 .changeset/happy-brooms-lick.md diff --git a/.changeset/happy-brooms-lick.md b/.changeset/happy-brooms-lick.md new file mode 100644 index 0000000000..e60aa51817 --- /dev/null +++ b/.changeset/happy-brooms-lick.md @@ -0,0 +1,5 @@ +--- +"@primer/css": patch +--- + +Add default `::selection` color diff --git a/src/base/base.scss b/src/base/base.scss index c12269ed19..6ee57b59b6 100644 --- a/src/base/base.scss +++ b/src/base/base.scss @@ -3,6 +3,10 @@ box-sizing: border-box; } +*::selection { + background-color: var(--color-accent-subtle); +} + input, select, textarea, From 5ac76ee9a1c77638c551dbbf018c358bd81f688f Mon Sep 17 00:00:00 2001 From: GitHub Design Systems Bot <30705008+primer-css@users.noreply.github.com> Date: Wed, 14 Jun 2023 00:43:15 +0200 Subject: [PATCH 05/20] Version Packages (#2458) Co-authored-by: github-actions[bot] --- .changeset/happy-brooms-lick.md | 5 ----- .changeset/shy-cats-hug.md | 5 ----- .changeset/swift-moles-jump.md | 5 ----- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 5 files changed, 11 insertions(+), 16 deletions(-) delete mode 100644 .changeset/happy-brooms-lick.md delete mode 100644 .changeset/shy-cats-hug.md delete mode 100644 .changeset/swift-moles-jump.md diff --git a/.changeset/happy-brooms-lick.md b/.changeset/happy-brooms-lick.md deleted file mode 100644 index e60aa51817..0000000000 --- a/.changeset/happy-brooms-lick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@primer/css": patch ---- - -Add default `::selection` color diff --git a/.changeset/shy-cats-hug.md b/.changeset/shy-cats-hug.md deleted file mode 100644 index 50b8fee6a2..0000000000 --- a/.changeset/shy-cats-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@primer/css": patch ---- - -Add width utility to limit line length for readability diff --git a/.changeset/swift-moles-jump.md b/.changeset/swift-moles-jump.md deleted file mode 100644 index ea6cce305e..0000000000 --- a/.changeset/swift-moles-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@primer/css": patch ---- - -Add new PostCSS fallback config diff --git a/CHANGELOG.md b/CHANGELOG.md index c2071607e5..197c12ea39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # @primer/css +## 21.0.3 + +### Patch Changes + +- [#2461](https://github.com/primer/css/pull/2461) [`abc89659`](https://github.com/primer/css/commit/abc8965913313bbb969db9e1148fb5add9327ec9) Thanks [@langermank](https://github.com/langermank)! - Add default `::selection` color + +- [#2410](https://github.com/primer/css/pull/2410) [`344224fc`](https://github.com/primer/css/commit/344224fccdef2f3a37ed931c512e400b47301ea2) Thanks [@dylanatsmith](https://github.com/dylanatsmith)! - Add width utility to limit line length for readability + +- [#2457](https://github.com/primer/css/pull/2457) [`352ed7b7`](https://github.com/primer/css/commit/352ed7b75585c686c996a5e7c2c29e20e41d0672) Thanks [@langermank](https://github.com/langermank)! - Add new PostCSS fallback config + ## 21.0.2 ### Patch Changes diff --git a/package.json b/package.json index 952fda5af9..0226148d74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@primer/css", - "version": "21.0.2", + "version": "21.0.3", "description": "The CSS implementation of GitHub's Primer Design System", "homepage": "https://primer.style/css", "author": "GitHub, Inc.", From 24c66b570c74a1729141e7610d2ada1d79a81437 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Wed, 14 Jun 2023 17:50:06 +0100 Subject: [PATCH 06/20] Clarify description of .width-comfortable (#2463) --- docs/content/utilities/layout.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/utilities/layout.md b/docs/content/utilities/layout.md index be98f26a72..18b42aac5b 100644 --- a/docs/content/utilities/layout.md +++ b/docs/content/utilities/layout.md @@ -204,7 +204,7 @@ Use `.width-auto` to reset width to `auto` (initial value). Typically used with ``` -Use `.width-comfortable` to set width to `65ch`. This can be used on text elements to shorten the line length for better readability. +Use `.width-comfortable` to set max width to `65ch`. This can be used on text elements to shorten the line length for better readability. ```html live

From 9204701416b547255a1ebaeb2bd8a20056ffb8d4 Mon Sep 17 00:00:00 2001 From: Katie Langerman <18661030+langermank@users.noreply.github.com> Date: Wed, 21 Jun 2023 13:56:27 -0700 Subject: [PATCH 07/20] Use `@primer/primitives` v8 colors with fallbacks (#2466) * bump * run stylelint * lint * bump release * Create tidy-brooms-search.md --- .changeset/tidy-brooms-search.md | 5 ++ package.json | 2 +- src/autocomplete/suggester.scss | 22 ++--- src/avatars/avatar-parent-child.scss | 4 +- src/avatars/circle-badge.scss | 6 +- src/base/base.scss | 12 +-- src/base/kbd.scss | 10 +-- src/base/normalize.scss | 4 +- src/box/box-overlay.scss | 6 +- src/branch-name/branch-name.scss | 12 +-- src/buttons/button.scss | 126 +++++++++++++-------------- src/buttons/misc.scss | 52 +++++------ src/color-modes/native.scss | 6 +- src/forms/form-control.scss | 36 ++++---- src/forms/form-group.scss | 58 ++++++------ src/forms/form-select.scss | 2 +- src/forms/radio-group.scss | 12 +-- src/header/header.scss | 14 +-- src/layout/app-frame.scss | 14 +-- src/layout/page-layout.scss | 4 +- src/layout/stack.scss | 2 +- src/markdown/blob-csv.scss | 4 +- src/markdown/code.scss | 6 +- src/markdown/footnotes.scss | 6 +- src/markdown/headings.scss | 8 +- src/markdown/images.scss | 6 +- src/markdown/markdown-body.scss | 8 +- src/markdown/tables.scss | 8 +- src/marketing/buttons/button.scss | 19 ++-- src/navigation/filter-list.scss | 16 ++-- src/navigation/sidenav.scss | 24 ++--- src/navigation/subnav.scss | 18 ++-- src/pagination/pagination.scss | 14 +-- src/select-menu/select-menu.scss | 82 ++++++++--------- src/support/mixins/misc.scss | 16 ++-- src/support/variables/misc.scss | 4 +- src/toasts/toasts.scss | 34 ++++---- src/tooltips/tooltips.scss | 14 +-- src/utilities/box-shadow.scss | 8 +- src/utilities/colors.scss | 118 ++++++++++++------------- src/utilities/details.scss | 2 +- stylelint.config.cjs | 10 ++- yarn.lock | 11 ++- 43 files changed, 428 insertions(+), 417 deletions(-) create mode 100644 .changeset/tidy-brooms-search.md diff --git a/.changeset/tidy-brooms-search.md b/.changeset/tidy-brooms-search.md new file mode 100644 index 0000000000..07d87b16a0 --- /dev/null +++ b/.changeset/tidy-brooms-search.md @@ -0,0 +1,5 @@ +--- +"@primer/css": patch +--- + +Use `@primer/primitives` v8 colors with fallbacks diff --git a/package.json b/package.json index 0226148d74..a0f42577d9 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@changesets/cli": "2.26.1", "@csstools/postcss-sass": "5.0.1", "@github/prettier-config": "0.0.6", - "@primer/stylelint-config": "^12.4.0", + "@primer/stylelint-config": "^12.7.1", "autoprefixer": "10.4.13", "chokidar-cli": "3.0.0", "cssstats": "4.0.5", diff --git a/src/autocomplete/suggester.scss b/src/autocomplete/suggester.scss index 87baf4dd9c..a7f61e0f96 100644 --- a/src/autocomplete/suggester.scss +++ b/src/autocomplete/suggester.scss @@ -11,20 +11,20 @@ margin-top: $spacer-4; list-style: none; cursor: pointer; - background: var(--color-canvas-overlay); - border: $border-width $border-style var(--color-border-default); + background: var(--overlay-bgColor, var(--color-canvas-overlay)); + border: $border-width $border-style var(--borderColor-default, var(--color-border-default)); border-radius: $border-radius; - box-shadow: var(--color-shadow-medium); + box-shadow: var(--shadow-resting-medium, var(--color-shadow-medium)); li { display: block; padding: $spacer-1 $spacer-2; font-weight: $font-weight-semibold; - border-bottom: $border-width $border-style var(--color-border-muted); + border-bottom: $border-width $border-style var(--borderColor-muted, var(--color-border-muted)); small { font-weight: $font-weight-normal; - color: var(--color-fg-muted); + color: var(--fgColor-muted, var(--color-fg-muted)); } &:last-child { @@ -39,12 +39,12 @@ } &:hover { - color: var(--color-fg-on-emphasis); + color: var(--fgColor-onEmphasis, var(--color-fg-on-emphasis)); text-decoration: none; - background: var(--color-accent-emphasis); + background: var(--bgColor-accent-emphasis, var(--color-accent-emphasis)); small { - color: var(--color-fg-on-emphasis); + color: var(--fgColor-onEmphasis, var(--color-fg-on-emphasis)); } .octicon { @@ -54,12 +54,12 @@ &[aria-selected='true'], &.navigation-focus { - color: var(--color-fg-on-emphasis); + color: var(--fgColor-onEmphasis, var(--color-fg-on-emphasis)); text-decoration: none; - background: var(--color-accent-emphasis); + background: var(--bgColor-accent-emphasis, var(--color-accent-emphasis)); small { - color: var(--color-fg-on-emphasis); + color: var(--fgColor-onEmphasis, var(--color-fg-on-emphasis)); } .octicon { diff --git a/src/avatars/avatar-parent-child.scss b/src/avatars/avatar-parent-child.scss index e3185f8068..01a5c7127e 100644 --- a/src/avatars/avatar-parent-child.scss +++ b/src/avatars/avatar-parent-child.scss @@ -10,8 +10,8 @@ position: absolute; right: -15%; bottom: -9%; - background-color: var(--color-canvas-default); // For transparent backgrounds + background-color: var(--bgColor-default, var(--color-canvas-default)); // For transparent backgrounds // stylelint-disable-next-line primer/borders border-radius: $border-radius-1; - box-shadow: var(--color-avatar-child-shadow); + box-shadow: var(--avatar-shadow, var(--color-avatar-child-shadow)); } diff --git a/src/avatars/circle-badge.scss b/src/avatars/circle-badge.scss index 657bbc931a..63032cfb63 100644 --- a/src/avatars/circle-badge.scss +++ b/src/avatars/circle-badge.scss @@ -4,9 +4,9 @@ display: flex; align-items: center; justify-content: center; - background-color: var(--color-canvas-default); + background-color: var(--bgColor-default, var(--color-canvas-default)); border-radius: 50%; - box-shadow: var(--color-shadow-medium); + box-shadow: var(--shadow-resting-medium, var(--color-shadow-medium)); } .CircleBadge-icon { @@ -46,7 +46,7 @@ width: 100%; content: ''; // stylelint-disable-next-line primer/borders - border-bottom: 2px dashed var(--color-border-default); + border-bottom: 2px dashed var(--borderColor-default, var(--color-border-default)); } .CircleBadge { diff --git a/src/base/base.scss b/src/base/base.scss index 6ee57b59b6..4ebf5f9b1b 100644 --- a/src/base/base.scss +++ b/src/base/base.scss @@ -4,7 +4,7 @@ } *::selection { - background-color: var(--color-accent-subtle); + background-color: var(--bgColor-accent-muted, var(--color-accent-subtle)); } input, @@ -20,12 +20,12 @@ body { font-family: $body-font; font-size: var(--body-font-size, $body-font-size); line-height: $body-line-height; - color: var(--color-fg-default); - background-color: var(--color-canvas-default); + color: var(--fgColor-default, var(--color-fg-default)); + background-color: var(--bgColor-default, var(--color-canvas-default)); } a { - color: var(--color-accent-fg); + color: var(--fgColor-accent, var(--color-accent-fg)); text-decoration: none; &:hover { @@ -50,7 +50,7 @@ label { // Custom styling for HTML5 validation bubbles (WebKit only) ::placeholder { - color: var(--color-fg-subtle); + color: var(--fgColor-muted, var(--color-fg-subtle)); opacity: 1; // override opacity in normalize.css } @@ -65,7 +65,7 @@ hr, overflow: hidden; background: transparent; border: 0; - border-bottom: $border-width $border-style var(--color-border-muted); + border-bottom: $border-width $border-style var(--borderColor-muted, var(--color-border-muted)); @include clearfix(); } diff --git a/src/base/kbd.scss b/src/base/kbd.scss index f6801b920d..c1386105c9 100644 --- a/src/base/kbd.scss +++ b/src/base/kbd.scss @@ -7,13 +7,13 @@ kbd { font: 11px $mono-font; // stylelint-disable-next-line primer/typography line-height: 10px; - color: var(--color-fg-default); + color: var(--fgColor-default, var(--color-fg-default)); vertical-align: middle; - background-color: var(--color-canvas-subtle); + background-color: var(--bgColor-muted, var(--color-canvas-subtle)); // stylelint-disable-next-line primer/borders - border: $border-style $border-width var(--color-neutral-muted); - border-bottom-color: var(--color-neutral-muted); + border: $border-style $border-width var(--borderColor-neutral-muted, var(--color-neutral-muted)); + border-bottom-color: var(--borderColor-neutral-muted, var(--color-neutral-muted)); border-radius: $border-radius; // stylelint-disable-next-line primer/box-shadow - box-shadow: inset 0 -1px 0 var(--color-neutral-muted); + box-shadow: inset 0 -1px 0 var(--borderColor-neutral-muted, var(--color-neutral-muted)); } diff --git a/src/base/normalize.scss b/src/base/normalize.scss index 5621566de1..9b38890e1f 100644 --- a/src/base/normalize.scss +++ b/src/base/normalize.scss @@ -153,8 +153,8 @@ h1 { */ mark { - background-color: var(--color-attention-subtle); - color: var(--color-fg-default); + background-color: var(--bgColor-attention-muted, var(--color-attention-subtle)); + color: var(--fgColor-default, var(--color-fg-default)); } /** diff --git a/src/box/box-overlay.scss b/src/box/box-overlay.scss index ed8f273364..5a82a501be 100644 --- a/src/box/box-overlay.scss +++ b/src/box/box-overlay.scss @@ -3,9 +3,9 @@ width: 448px; margin-right: auto; margin-left: auto; - background-color: var(--color-canvas-default); + background-color: var(--bgColor-default, var(--color-canvas-default)); background-clip: padding-box; - border-color: var(--color-border-default); + border-color: var(--borderColor-default, var(--color-border-default)); // stylelint-disable-next-line primer/box-shadow box-shadow: 0 0 18px rgba(0, 0, 0, 0.4); @@ -36,7 +36,7 @@ .help { padding-top: $spacer-2; margin: 0; - color: var(--color-fg-muted); + color: var(--fgColor-muted, var(--color-fg-muted)); text-align: center; } } diff --git a/src/branch-name/branch-name.scss b/src/branch-name/branch-name.scss index 600e99b8a9..c18c746e50 100644 --- a/src/branch-name/branch-name.scss +++ b/src/branch-name/branch-name.scss @@ -7,25 +7,25 @@ // stylelint-disable-next-line primer/spacing padding: 2px 6px; font: 12px $mono-font; - color: var(--color-fg-muted); + color: var(--fgColor-muted, var(--color-fg-muted)); word-break: break-all; - background-color: var(--color-accent-subtle); + background-color: var(--bgColor-accent-muted, var(--color-accent-subtle)); border-radius: $border-radius; .octicon { // stylelint-disable-next-line primer/spacing margin: 1px -2px 0 0; - color: var(--color-fg-muted); + color: var(--fgColor-muted, var(--color-fg-muted)); } } // When a branch name is a link a.branch-name { - color: var(--color-accent-fg); - background-color: var(--color-accent-subtle); + color: var(--fgColor-accent, var(--color-accent-fg)); + background-color: var(--bgColor-accent-muted, var(--color-accent-subtle)); .octicon { - color: var(--color-accent-fg); + color: var(--fgColor-accent, var(--color-accent-fg)); } } diff --git a/src/buttons/button.scss b/src/buttons/button.scss index 27563db247..9e967a42a9 100644 --- a/src/buttons/button.scss +++ b/src/buttons/button.scss @@ -36,7 +36,7 @@ .octicon { margin-right: $spacer-1; - color: var(--color-fg-muted); + color: var(--fgColor-muted, var(--color-fg-muted)); vertical-align: text-bottom; &:only-child { @@ -50,7 +50,7 @@ color: inherit; text-shadow: none; vertical-align: top; - background-color: var(--color-btn-counter-bg); + background-color: var(--buttonCounter-default-bgColor-rest, var(--color-btn-counter-bg)); } .dropdown-caret { @@ -62,42 +62,42 @@ // Default button .btn { - color: var(--color-btn-text); - background-color: var(--color-btn-bg); - border-color: var(--color-btn-border); - box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow); + color: var(--button-default-fgColor-rest, var(--color-btn-text)); + background-color: var(--button-default-bgColor-rest, var(--color-btn-bg)); + border-color: var(--button-default-borderColor-rest, var(--color-btn-border)); + box-shadow: var(--button-default-shadow-resting, var(--color-btn-shadow)), var(--button-default-shadow-inset, var(--color-btn-inset-shadow)); transition: 80ms cubic-bezier(0.33, 1, 0.68, 1); transition-property: color, background-color, box-shadow, border-color; &:hover, &.hover, [open] > & { - background-color: var(--color-btn-hover-bg); - border-color: var(--color-btn-hover-border); + background-color: var(--button-default-bgColor-hover, var(--color-btn-hover-bg)); + border-color: var(--button-default-borderColor-hover, var(--color-btn-hover-border)); transition-duration: 0.1s; } &:active { - background-color: var(--color-btn-active-bg); - border-color: var(--color-btn-active-border); + background-color: var(--button-default-bgColor-active, var(--color-btn-active-bg)); + border-color: var(--button-default-borderColor-active, var(--color-btn-active-border)); transition: none; } &.selected, &[aria-selected='true'] { - background-color: var(--color-btn-selected-bg); - box-shadow: var(--color-primer-shadow-inset); + background-color: var(--button-default-bgColor-selected, var(--color-btn-selected-bg)); + box-shadow: var(--shadow-inset, var(--color-primer-shadow-inset)); } &:disabled, &.disabled, &[aria-disabled='true'] { - color: var(--color-primer-fg-disabled); - background-color: var(--color-btn-bg); - border-color: var(--color-btn-border); + color: var(--fgColor-disabled, var(--color-primer-fg-disabled)); + background-color: var(--button-default-bgColor-rest, var(--color-btn-bg)); + border-color: var(--button-default-borderColor-rest, var(--color-btn-border)); .octicon { - color: var(--color-primer-fg-disabled); + color: var(--fgColor-disabled, var(--color-primer-fg-disabled)); } } } @@ -105,16 +105,16 @@ // Primary button .btn-primary { - color: var(--color-btn-primary-text); - background-color: var(--color-btn-primary-bg); - border-color: var(--color-btn-primary-border); - box-shadow: var(--color-btn-primary-shadow), var(--color-btn-primary-inset-shadow); + color: var(--button-primary-fgColor-rest, var(--color-btn-primary-text)); + background-color: var(--button-primary-bgColor-rest, var(--color-btn-primary-bg)); + border-color: var(--button-primary-borderColor-rest, var(--color-btn-primary-border)); + box-shadow: var(--shadow-resting-small, var(--color-btn-primary-shadow)), var(--shadow-highlight, var(--color-btn-primary-inset-shadow)); &:hover, &.hover, [open] > & { - background-color: var(--color-btn-primary-hover-bg); - border-color: var(--color-btn-primary-hover-border); + background-color: var(--button-primary-bgColor-hover, var(--color-btn-primary-hover-bg)); + border-color: var(--button-primary-borderColor-hover, var(--color-btn-primary-hover-border)); } // fallback :focus state @@ -136,29 +136,29 @@ &:active, &.selected, &[aria-selected='true'] { - background-color: var(--color-btn-primary-selected-bg); - box-shadow: var(--color-btn-primary-selected-shadow); + background-color: var(--button-primary-bgColor-active, var(--color-btn-primary-selected-bg)); + box-shadow: var(--button-primary-shadow-selected, var(--color-btn-primary-selected-shadow)); } &:disabled, &.disabled, &[aria-disabled='true'] { - color: var(--color-btn-primary-disabled-text); - background-color: var(--color-btn-primary-disabled-bg); - border-color: var(--color-btn-primary-disabled-border); + color: var(--button-primary-fgColor-disabled, var(--color-btn-primary-disabled-text)); + background-color: var(--button-primary-bgColor-disabled, var(--color-btn-primary-disabled-bg)); + border-color: var(--button-primary-borderColor-disabled, var(--color-btn-primary-disabled-border)); .octicon { - color: var(--color-btn-primary-disabled-text); + color: var(--button-primary-fgColor-disabled, var(--color-btn-primary-disabled-text)); } } .Counter { color: inherit; - background-color: var(--color-btn-primary-counter-bg); + background-color: var(--buttonCounter-primary-bgColor-rest, var(--color-btn-primary-counter-bg)); } .octicon { - color: var(--color-btn-primary-icon); + color: var(--button-primary-iconColor-rest, var(--color-btn-primary-icon)); } } @@ -185,17 +185,17 @@ a.btn-primary { // Outline button .btn-outline { - color: var(--color-btn-outline-text); + color: var(--button-outline-fgColor-rest, var(--color-btn-outline-text)); &:hover, [open] > & { - color: var(--color-btn-outline-hover-text); - background-color: var(--color-btn-outline-hover-bg); - border-color: var(--color-btn-outline-hover-border); - box-shadow: var(--color-btn-outline-hover-shadow), var(--color-btn-outline-hover-inset-shadow); + color: var(--button-outline-fgColor-hover, var(--color-btn-outline-hover-text)); + background-color: var(--button-outline-bgColor-hover, var(--color-btn-outline-hover-bg)); + border-color: var(--button-outline-borderColor-hover, var(--color-btn-outline-hover-border)); + box-shadow: var(--shadow-resting-small, var(--color-btn-outline-hover-shadow)), var(--shadow-highlight, var(--color-btn-outline-hover-inset-shadow)); .Counter { - background-color: var(--color-btn-outline-hover-counter-bg); + background-color: var(--buttonCounter-outline-bgColor-hover, var(--color-btn-outline-hover-counter-bg)); } .octicon { @@ -206,10 +206,10 @@ a.btn-primary { &:active, &.selected, &[aria-selected='true'] { - color: var(--color-btn-outline-selected-text); - background-color: var(--color-btn-outline-selected-bg); - border-color: var(--color-btn-outline-selected-border); - box-shadow: var(--color-btn-outline-selected-shadow); + color: var(--button-outline-fgColor-active, var(--color-btn-outline-selected-text)); + background-color: var(--button-outline-bgColor-active, var(--color-btn-outline-selected-bg)); + border-color: var(--button-outline-borderColor-active, var(--color-btn-outline-selected-border)); + box-shadow: var(--button-outline-shadow-selected, var(--color-btn-outline-selected-shadow)); // fallback :focus state &:focus { @@ -231,76 +231,76 @@ a.btn-primary { &:disabled, &.disabled, &[aria-disabled='true'] { - color: var(--color-btn-outline-disabled-text); - background-color: var(--color-btn-outline-disabled-bg); - border-color: var(--color-btn-border); + color: var(--button-outline-fgColor-disabled, var(--color-btn-outline-disabled-text)); + background-color: var(--button-outline-bgColor-disabled, var(--color-btn-outline-disabled-bg)); + border-color: var(--button-default-borderColor-rest, var(--color-btn-border)); box-shadow: none; .Counter { - background-color: var(--color-btn-outline-disabled-counter-bg); + background-color: var(--buttonCounter-outline-bgColor-disabled, var(--color-btn-outline-disabled-counter-bg)); } } .Counter { color: inherit; - background-color: var(--color-btn-outline-counter-bg); + background-color: var(--buttonCounter-outline-bgColor-rest, var(--color-btn-outline-counter-bg)); } } // Danger button .btn-danger { - color: var(--color-btn-danger-text); + color: var(--button-danger-fgColor-rest, var(--color-btn-danger-text)); .octicon { - color: var(--color-btn-danger-icon); + color: var(--button-danger-iconColor-rest, var(--color-btn-danger-icon)); } &:hover, [open] > & { - color: var(--color-btn-danger-hover-text); - background-color: var(--color-btn-danger-hover-bg); - border-color: var(--color-btn-danger-hover-border); - box-shadow: var(--color-btn-danger-hover-shadow), var(--color-btn-danger-hover-inset-shadow); + color: var(--button-danger-fgColor-hover, var(--color-btn-danger-hover-text)); + background-color: var(--button-danger-bgColor-hover, var(--color-btn-danger-hover-bg)); + border-color: var(--button-danger-borderColor-hover, var(--color-btn-danger-hover-border)); + box-shadow: var(--shadow-resting-small, var(--color-btn-danger-hover-shadow)), var(--shadow-highlight, var(--color-btn-danger-hover-inset-shadow)); .Counter { - background-color: var(--color-btn-danger-hover-counter-bg); + background-color: var(--buttonCounter-danger-bgColor-hover, var(--color-btn-danger-hover-counter-bg)); } .octicon { - color: var(--color-btn-danger-hover-icon); + color: var(--button-danger-iconColor-hover, var(--color-btn-danger-hover-icon)); } } &:active, &.selected, &[aria-selected='true'] { - color: var(--color-btn-danger-selected-text); - background-color: var(--color-btn-danger-selected-bg); - border-color: var(--color-btn-danger-selected-border); - box-shadow: var(--color-btn-danger-selected-shadow); + color: var(--button-danger-fgColor-active, var(--color-btn-danger-selected-text)); + background-color: var(--button-danger-bgColor-active, var(--color-btn-danger-selected-bg)); + border-color: var(--button-danger-borderColor-active, var(--color-btn-danger-selected-border)); + box-shadow: var(--button-danger-shadow-selected, var(--color-btn-danger-selected-shadow)); } &:disabled, &.disabled, &[aria-disabled='true'] { - color: var(--color-btn-danger-disabled-text); - background-color: var(--color-btn-danger-disabled-bg); - border-color: var(--color-btn-border); + color: var(--button-danger-fgColor-disabled, var(--color-btn-danger-disabled-text)); + background-color: var(--button-danger-bgColor-disabled, var(--color-btn-danger-disabled-bg)); + border-color: var(--button-default-borderColor-rest, var(--color-btn-border)); box-shadow: none; .Counter { - background-color: var(--color-btn-danger-disabled-counter-bg); + background-color: var(--buttonCounter-danger-bgColor-disabled, var(--color-btn-danger-disabled-counter-bg)); } .octicon { - color: var(--color-btn-danger-disabled-text); + color: var(--button-danger-fgColor-disabled, var(--color-btn-danger-disabled-text)); } } .Counter { color: inherit; - background-color: var(--color-btn-danger-counter-bg); + background-color: var(--buttonCounter-danger-bgColor-rest, var(--color-btn-danger-counter-bg)); } } diff --git a/src/buttons/misc.scss b/src/buttons/misc.scss index 328b2fe27a..399392d681 100644 --- a/src/buttons/misc.scss +++ b/src/buttons/misc.scss @@ -7,7 +7,7 @@ display: inline-block; padding: 0; font-size: inherit; - color: var(--color-accent-fg); + color: var(--fgColor-accent, var(--color-accent-fg)); text-decoration: none; white-space: nowrap; cursor: pointer; @@ -24,7 +24,7 @@ &[aria-disabled='true'] { &, &:hover { - color: var(--color-primer-fg-disabled); + color: var(--fgColor-disabled, var(--color-primer-fg-disabled)); cursor: default; } } @@ -42,7 +42,7 @@ // // Typically used as a "cancel" button next to a .btn .btn-invisible { - color: var(--color-accent-fg); + color: var(--fgColor-accent, var(--color-accent-fg)); background-color: transparent; // Reset default gradient backgrounds and colors border: 0; border-radius: $border-radius; @@ -50,8 +50,8 @@ &:hover, &.zeroclipboard-is-hover { - color: var(--color-accent-fg); - background-color: var(--color-btn-hover-bg); + color: var(--fgColor-accent, var(--color-accent-fg)); + background-color: var(--button-default-bgColor-hover, var(--color-btn-hover-bg)); outline: none; box-shadow: none; } @@ -60,21 +60,21 @@ &.selected, &[aria-selected='true'], &.zeroclipboard-is-active { - color: var(--color-accent-fg); + color: var(--fgColor-accent, var(--color-accent-fg)); background: none; - border-color: var(--color-btn-active-border); + border-color: var(--button-default-borderColor-active, var(--color-btn-active-border)); @include focusOutline; } &:active &.zeroclipboard-is-active { - background-color: var(--color-btn-selected-bg); + background-color: var(--button-default-bgColor-selected, var(--color-btn-selected-bg)); } &:disabled, &.disabled, &[aria-disabled='true'] { - color: var(--color-primer-fg-disabled); + color: var(--fgColor-disabled, var(--color-primer-fg-disabled)); background-color: transparent; } } @@ -89,7 +89,7 @@ // stylelint-disable-next-line primer/spacing margin-left: 5px; line-height: $lh-condensed-ultra; - color: var(--color-fg-muted); + color: var(--fgColor-muted, var(--color-fg-muted)); vertical-align: middle; // For ` - {focusElement && focusMethod()} - -) - -export const Playground = ButtonTemplate.bind({}) -Playground.args = { - closeBtn: false, - focusElement: false, - focusAllElements: false -} diff --git a/docs/src/stories/components/Button/ButtonFeatures.stories.jsx b/docs/src/stories/components/Button/ButtonFeatures.stories.jsx deleted file mode 100644 index 853ee49e81..0000000000 --- a/docs/src/stories/components/Button/ButtonFeatures.stories.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import {ButtonTemplate} from './Button.stories' - -export default { - title: 'Components/Button/Features' -} - -export const LeadingVisual = ButtonTemplate.bind({}) -LeadingVisual.storyName = 'Leading icon' -LeadingVisual.args = { - label: 'Open in Desktop', - leadingVisual: - '' -} - -export const TrailingVisual = ButtonTemplate.bind({}) -TrailingVisual.storyName = 'Trailing icon' -TrailingVisual.args = { - label: 'Open in Desktop', - trailingVisual: - '' -} - -export const Disabled = ButtonTemplate.bind({}) -Disabled.storyName = 'Disabled' -Disabled.args = { - label: 'Disabled', - disabled: true -} - -export const DisabledWithLeadingVisual = ButtonTemplate.bind({}) -DisabledWithLeadingVisual.storyName = 'Disabled with leading visual' -DisabledWithLeadingVisual.args = { - label: 'Disabled', - disabled: true, - leadingVisual: - '' -} - -export const Selected = ButtonTemplate.bind({}) -Selected.storyName = 'Selected' -Selected.args = { - label: 'Selected', - selected: true -} - -export const SelectedWithLeadingVisual = ButtonTemplate.bind({}) -SelectedWithLeadingVisual.storyName = 'Selected with leading visual' -SelectedWithLeadingVisual.args = { - label: 'Selected', - selected: true, - leadingVisual: - '' -} diff --git a/docs/src/stories/components/Dialog/Dialog.stories.jsx b/docs/src/stories/components/Dialog/Dialog.stories.jsx deleted file mode 100644 index c43b6a8f0e..0000000000 --- a/docs/src/stories/components/Dialog/Dialog.stories.jsx +++ /dev/null @@ -1,388 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import {OverlayTemplate} from '../../ui-patterns/Overlay/Overlay.stories' - -export default { - title: 'Components/Dialog', - parameters: { - layout: 'padded' - }, - - excludeStories: ['DialogTemplate'], - argTypes: { - title: { - name: 'title', - type: {name: 'string', required: false}, - description: 'The heading element of the dialog', - defaultValue: '', - table: { - category: 'HTML' - } - }, - description: { - name: 'description', - type: 'string', - description: 'The sub-heading element of the dialog', - defaultValue: '', - table: { - category: 'HTML' - } - }, - toggleOverlay: { - control: {type: 'boolean'}, - description: 'show/hide overlay', - defaultValue: false, - table: { - category: 'Demo' - } - }, - showCloseButton: { - control: {type: 'boolean'}, - description: 'show/hide close button', - defaultValue: true, - table: { - category: 'Demo' - } - }, - showFooterButton: { - control: {type: 'boolean'}, - description: 'show/hide footer button', - defaultValue: false, - table: { - category: 'Demo' - } - }, - width: { - options: [0, 1, 2, 3, 4, 5], // iterator - mapping: [ - 'Overlay--width-auto', - 'Overlay--width-small', - 'Overlay--width-medium', - 'Overlay--width-large', - 'Overlay--width-xlarge', - 'Overlay--width-xxlarge' - ], // values - control: { - type: 'inline-radio', - labels: ['auto', 'small', 'medium', 'large', 'xlarge', 'xxlarge'] - }, - description: 'Width options: small: 256px, medium: 320px, large: 480px, xlarge: 640px, xxlarge: 960px', - table: { - category: 'CSS' - } - }, - height: { - options: [0, 1, 2, 3, 4, 5], // iterator - mapping: [ - 'Overlay--height-auto', - 'Overlay--height-xsmall', - 'Overlay--height-small', - 'Overlay--height-medium', - 'Overlay--height-large', - 'Overlay--height-xlarge' - ], // values - control: { - type: 'inline-radio', - labels: ['auto', 'xsmall', 'small', 'medium', 'large', 'xlarge', 'xxlarge'] - }, - description: - 'Height options: auto: adjusts to content, xsmall: 192px, small: 256px, medium: 320px, large: 432px, xlarge: 600px', - table: { - category: 'CSS' - } - }, - headerVariant: { - options: [0, 1], // iterator - mapping: ['', 'Overlay-header--large'], // values - control: { - type: 'inline-radio', - labels: ['medium (default)', 'large'] - }, - description: 'medium (default), large header/description font-size + spacing', - table: { - category: 'CSS' - } - }, - bodyPaddingVariant: { - options: [0, 1, 2], // iterator - mapping: ['', 'Overlay-body--paddingCondensed', 'Overlay-body--paddingNone'], // values - control: { - type: 'inline-radio', - labels: ['normal (default)', 'condensed', 'none'] - }, - description: 'body spacing', - table: { - category: 'CSS' - } - }, - variantNarrow: { - options: [0, 1, 2, 3], // iterator - mapping: [ - 'Overlay-backdrop--center-whenNarrow', - 'Overlay-backdrop--anchor-whenNarrow', - 'Overlay-backdrop--side-whenNarrow', - 'Overlay-backdrop--full-whenNarrow' - ], // values - control: { - type: 'inline-radio', - labels: ['center', 'anchored', 'side', 'full'] - }, - description: '', - table: { - category: 'Variant' - } - }, - variantRegular: { - options: [0, 1, 2, 3], // iterator - mapping: [ - 'Overlay-backdrop--center', - 'Overlay-backdrop--anchor', - 'Overlay-backdrop--side', - 'Overlay-backdrop--full' - ], // values - control: { - type: 'inline-radio', - labels: ['center', 'anchored', 'side', 'full'] - }, - description: '', - table: { - category: 'Variant' - } - }, - placementNarrow: { - options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], - mapping: [ - 'Overlay-backdrop--placement-top-whenNarrow', - '', - '', - '', - 'Overlay-backdrop--placement-bottom-whenNarrow', - '', - '', - '', - 'Overlay-backdrop--placement-right-whenNarrow', - '', - '', - '', - 'Overlay-backdrop--placement-left-whenNarrow', - '', - '', - '', - '' - ], - control: { - type: 'inline-radio', - labels: [ - 'top', - 'top-start', - 'top-center', - 'top-end', - 'bottom', - 'bottom-start', - 'bottom-center', - 'bottom-end', - 'right', - 'right-start', - 'right-center', - 'right-end', - 'left', - 'left-start', - 'left-center', - 'left-end', - 'reset' - ] - }, - description: 'Positions overlay for narrow viewport range', - table: { - category: 'Placement' - } - }, - placementRegular: { - options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], - mapping: [ - 'Overlay-backdrop--placement-top', - '', - '', - '', - 'Overlay-backdrop--placement-bottom', - '', - '', - '', - 'Overlay-backdrop--placement-right', - '', - '', - '', - 'Overlay-backdrop--placement-left', - '', - '', - '', - '' - ], - control: { - type: 'inline-radio', - labels: [ - 'top', - 'top-start', - 'top-center', - 'top-end', - 'bottom', - 'bottom-start', - 'bottom-center', - 'bottom-end', - 'right', - 'right-start', - 'right-center', - 'right-end', - 'left', - 'left-start', - 'left-center', - 'left-end', - 'reset' - ] - }, - description: 'Positions overlay for narrow viewport range', - table: { - category: 'Placement' - } - }, - headerRegion: { - control: {type: 'boolean'}, - description: - 'A header region may be used to provide context to the user by displaying a title, description, and offering an easy-to-escape route with a Close button. Headers may also provide ways for the user to interact with the content, such as with search and tabs.', - defaultValue: true, - table: { - category: 'Demo' - } - }, - footerRegion: { - control: {type: 'boolean'}, - description: - 'The footer region may be used to show confirmation actions, navigation links, or other important elements that should appear outside of the content scrolling region.', - defaultValue: true, - table: { - category: 'Demo' - } - }, - showFooterDivider: { - control: {type: 'boolean'}, - defaultValue: false, - description: 'Show dividers above footer', - table: { - category: 'CSS' - } - }, - showHeaderDivider: { - control: {type: 'boolean'}, - defaultValue: false, - description: 'Show dividers below header', - table: { - category: 'CSS' - } - }, - headerContentSlot: { - description: 'Slot for additional header content', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - actionContentSlot: { - description: 'Slot for additional header action', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - motion: { - options: [0, 1], // iterator - mapping: [null, 'Overlay--motion-scaleFade'], // values - control: { - type: 'inline-radio', - labels: ['none', 'scaleFade'] - }, - description: 'Animation options for show/hide overlay', - table: { - category: 'CSS' - } - }, - footerContentAlign: { - options: [0, 1, 2], // iterator - mapping: ['Overlay-footer--alignStart', 'Overlay-footer--alignCenter', 'Overlay-footer--alignEnd'], // values - control: { - type: 'inline-radio', - labels: ['start', 'center', 'end'] - }, - description: 'Align footer contents', - table: { - category: 'CSS' - } - }, - role: { - description: 'Semantic role', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - ariaLabelledy: { - description: 'aria-labelledby', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - ariaDescribedby: { - description: 'aria-describedby', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - dataFocusTrap: { - description: 'data-focus-trap', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - titleId: { - description: 'title id', - control: {type: 'string'}, - table: { - category: 'HTML' - } - }, - descriptionId: { - description: 'description id', - control: {type: 'string'}, - table: { - category: 'HTML' - } - } - } -} - -export const Playground = OverlayTemplate.bind({}) -Playground.args = { - ...OverlayTemplate.args, - title: 'Dialog title', - description: 'Optional dialog description', - role: 'dialog', - width: 2, - height: 3, - ariaLabelledby: 'title-id', - ariaDescribedby: 'description-id', - dataFocusTrap: 'active', - footerContentAlign: 2, - showCloseButton: true, - headerVariant: 0, - bodyPaddingVariant: 0, - motion: 1, - descriptionId: 'description-id', - titleId: 'title-id', - showFooterDivider: false, - children:

Dialog body

, - headerRegion: true, - variantNarrow: 3, - variantRegular: 0 -} diff --git a/docs/src/stories/components/Forms/Checkbox.stories.jsx b/docs/src/stories/components/Forms/Checkbox.stories.jsx deleted file mode 100644 index 0dac6fdc95..0000000000 --- a/docs/src/stories/components/Forms/Checkbox.stories.jsx +++ /dev/null @@ -1,122 +0,0 @@ -import React from 'react' -import clsx from 'clsx' - -export default { - title: 'Components/Forms/Checkbox', - parameters: { - layout: 'padded' - }, - decorators: [ - Story => ( -
- - - ) - ], - excludeStories: ['CheckboxTemplate'], - argTypes: { - disabled: { - description: 'disabled field', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - note: { - type: 'string', - name: 'note', - description: 'string', - table: { - category: 'HTML' - } - }, - label: { - type: 'string', - name: 'label', - description: 'string', - table: { - category: 'HTML' - } - }, - highlight: { - control: {type: 'boolean'}, - description: 'highlight label', - table: { - category: 'CSS' - } - }, - checked: { - control: {type: 'boolean'}, - description: 'checkbox state', - table: { - category: 'CSS' - } - }, - focusElement: { - control: {type: 'boolean'}, - description: 'set focus on element', - table: { - category: 'Interactive' - } - }, - focusAllElements: { - control: {type: 'boolean'}, - description: 'set focus on all elements for viewing in all themes', - table: { - category: 'Interactive' - } - }, - type: { - options: [0, 1], // iterator - mapping: ['checkbox', 'radio'], // values - control: { - type: 'inline-radio', - labels: ['checkbox', 'radio'] // public labels - }, - description: 'input type' - } - } -} - -const focusMethod = function getFocus() { - // find the focusable element - var checkbox = document.getElementsByTagName('input')[0] - // set focus on element - checkbox.focus() -} - -export const CheckboxTemplate = ({label, note, highlight, disabled, checked, focusElement, focusAllElements, type}) => ( - <> -
- - {note && ( -

- {note} -

- )} -
- {focusElement && focusMethod()} - -) - -export const Playground = CheckboxTemplate.bind({}) -Playground.args = { - label: 'Label', - focusElement: false, - disabled: false, - checked: false, - highlight: false, - note: '', - type: 'checkbox', - focusAllElements: false, - type: 'checkbox' -} diff --git a/docs/src/stories/components/Forms/Fieldset.stories.jsx b/docs/src/stories/components/Forms/Fieldset.stories.jsx deleted file mode 100644 index 8beb1a6129..0000000000 --- a/docs/src/stories/components/Forms/Fieldset.stories.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' - -export default { - title: 'Components/Forms/Fieldset', - decorators: [ - Story => ( -
- - - ) - ], - argTypes: { - disabled: { - description: 'disabled fieldset', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - } - } -} - -const FieldsetTemplate = ({disabled}) => ( -
- - - - - -
-) - -export const Playground = FieldsetTemplate.bind({}) -Playground.args = { - disabled: false -} diff --git a/docs/src/stories/components/Forms/FormGroup.stories.jsx b/docs/src/stories/components/Forms/FormGroup.stories.jsx deleted file mode 100644 index 84b6d764ac..0000000000 --- a/docs/src/stories/components/Forms/FormGroup.stories.jsx +++ /dev/null @@ -1,165 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import {InputTemplate} from './Input.stories' - -export default { - title: 'Components/Forms/FormGroup', - parameters: { - layout: 'padded' - }, - decorators: [ - Story => ( -
- - - ) - ], - excludeStories: ['FormGroupTemplate'], - argTypes: { - size: { - options: [0, 1, 2], // iterator - mapping: [null, 'input-sm', 'input-lg'], // values - control: { - type: 'select', - labels: ['default', 'small', 'large'] - }, - table: { - category: 'CSS' - } - }, - block: { - description: 'full width', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - monospace: { - description: 'monospace text', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - contrast: { - description: 'change input background to light gray', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - disabled: { - description: 'disabled field', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - hideWebKit: { - description: 'hide WebKit autofill icon', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - placeholder: { - type: 'string', - name: 'placeholder', - description: 'string', - table: { - category: 'HTML' - } - }, - label: { - type: 'string', - name: 'label', - description: 'string', - table: { - category: 'HTML' - } - }, - type: { - name: 'type', - type: 'string', - description: 'type', - table: { - category: 'HTML' - } - }, - id: { - name: 'id', - type: 'string', - description: 'id', - table: { - category: 'HTML' - } - }, - focusElement: { - control: {type: 'boolean'}, - description: 'set focus on element', - table: { - category: 'Interactive' - } - }, - focusAllElements: { - control: {type: 'boolean'}, - description: 'set focus on all elements for viewing in all themes', - table: { - category: 'Interactive' - } - } - } -} - -const focusMethod = function getFocus() { - // find the focusable element - var input = document.getElementsByTagName('input')[0] - // set focus on element - input.focus() -} - -export const FormGroupTemplate = ({ - label, - type, - id, - size, - block, - placeholder, - contrast, - disabled, - hideWebKit, - monospace, - focusElement, - focusAllElements -}) => ( - <> -
-
-
- -
-
- -
-

- monalisa is not available. monalisa-beep, monalisa-cyber, or monalisa87 are available. -

-
-
- -) - -export const Playground = FormGroupTemplate.bind({}) -Playground.args = { - type: 'email', - id: 'some-id', - placeholder: 'Email address', - label: 'Enter email address', - block: false, - hideWebKit: false, - monospace: false, - contrast: false, - disabled: false, - focusElement: false, - focusAllElements: false -} diff --git a/docs/src/stories/components/Forms/Input.stories.jsx b/docs/src/stories/components/Forms/Input.stories.jsx deleted file mode 100644 index c2aac751f5..0000000000 --- a/docs/src/stories/components/Forms/Input.stories.jsx +++ /dev/null @@ -1,168 +0,0 @@ -import React from 'react' -import clsx from 'clsx' - -export default { - title: 'Components/Forms/Input', - parameters: { - layout: 'padded' - }, - decorators: [ - Story => ( -
- - - ) - ], - excludeStories: ['InputTemplate'], - argTypes: { - size: { - options: [0, 1, 2], // iterator - mapping: [null, 'input-sm', 'input-lg'], // values - control: { - type: 'select', - labels: ['default', 'small', 'large'] - }, - table: { - category: 'CSS' - } - }, - block: { - description: 'full width', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - monospace: { - description: 'monospace text', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - contrast: { - description: 'change input background to light gray', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - disabled: { - description: 'disabled field', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - hideWebKit: { - description: 'hide WebKit autofill icon', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - placeholder: { - type: 'string', - name: 'placeholder', - description: 'string', - table: { - category: 'HTML' - } - }, - label: { - type: 'string', - name: 'label', - description: 'string', - table: { - category: 'HTML' - } - }, - type: { - name: 'type', - type: 'string', - description: 'type', - table: { - category: 'HTML' - } - }, - id: { - name: 'id', - type: 'string', - description: 'id', - table: { - category: 'HTML' - } - }, - focusElement: { - control: {type: 'boolean'}, - description: 'set focus on element', - table: { - category: 'Interactive' - } - }, - focusAllElements: { - control: {type: 'boolean'}, - description: 'set focus on all elements for viewing in all themes', - table: { - category: 'Interactive' - } - } - } -} - -const focusMethod = function getFocus() { - // find the focusable element - var input = document.getElementsByTagName('input')[0] - // set focus on element - input.focus() -} - -export const InputTemplate = ({ - label, - type, - id, - size, - block, - placeholder, - contrast, - disabled, - hideWebKit, - monospace, - focusElement, - focusAllElements -}) => ( - <> - - - {focusElement && focusMethod()} - -) - -export const Playground = InputTemplate.bind({}) -Playground.args = { - type: 'email', - id: 'some-id', - placeholder: 'Email address', - label: 'Enter email address', - block: false, - hideWebKit: false, - monospace: false, - contrast: false, - disabled: false, - focusElement: false, - focusAllElements: false -} diff --git a/docs/src/stories/components/Forms/Radio.stories.jsx b/docs/src/stories/components/Forms/Radio.stories.jsx deleted file mode 100644 index 33835a50cb..0000000000 --- a/docs/src/stories/components/Forms/Radio.stories.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import {CheckboxTemplate} from './Checkbox.stories' - -export default { - title: 'Components/Forms/Radio', - parameters: { - layout: 'padded' - }, - decorators: [ - Story => ( -
- - - ) - ] -} - -export const Playground = CheckboxTemplate.bind({}) -Playground.args = { - label: 'Label', - focusElement: false, - disabled: false, - checked: false, - highlight: false, - note: '', - type: 'radio', - focusAllElements: false -} diff --git a/docs/src/stories/components/Forms/Select.stories.jsx b/docs/src/stories/components/Forms/Select.stories.jsx deleted file mode 100644 index f8303e7efc..0000000000 --- a/docs/src/stories/components/Forms/Select.stories.jsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from 'react' -import clsx from 'clsx' - -export default { - title: 'Components/Forms/Select', - parameters: { - layout: 'padded' - }, - decorators: [ - Story => ( -
- - - ) - ], - excludeStories: ['SelectTemplate'], - argTypes: { - size: { - options: [0, 1], // iterator - mapping: [null, 'select-sm'], // values - control: { - type: 'select', - labels: ['default', 'small'] - }, - table: { - category: 'CSS' - } - }, - disabled: { - description: 'disabled field', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - placeholder: { - type: 'string', - name: 'placeholder', - description: 'string', - table: { - category: 'HTML' - } - }, - label: { - type: 'string', - name: 'label', - description: 'string', - table: { - category: 'HTML' - } - }, - id: { - name: 'id', - type: 'string', - description: 'id', - table: { - category: 'HTML' - } - }, - focusElement: { - control: {type: 'boolean'}, - description: 'set focus on element', - table: { - category: 'Interactive' - } - }, - focusAllElements: { - control: {type: 'boolean'}, - description: 'set focus on all elements for viewing in all themes', - table: { - category: 'Interactive' - } - } - } -} - -const focusMethod = function getFocus() { - // find the focusable element - var select = document.getElementsByTagName('select')[0] - // set focus on element - select.focus() -} - -export const SelectTemplate = ({label, id, size, placeholder, disabled, focusElement, focusAllElements}) => ( - <> - - - {focusElement && focusMethod()} - -) - -export const Playground = SelectTemplate.bind({}) -Playground.args = { - id: 'some-id', - placeholder: 'Select', - label: 'Select one', - focusElement: false, - focusAllElements: false -} diff --git a/docs/src/stories/components/Forms/Textarea.stories.jsx b/docs/src/stories/components/Forms/Textarea.stories.jsx deleted file mode 100644 index 0e80851b44..0000000000 --- a/docs/src/stories/components/Forms/Textarea.stories.jsx +++ /dev/null @@ -1,154 +0,0 @@ -import React from 'react' -import clsx from 'clsx' - -export default { - title: 'Components/Forms/Textarea', - parameters: { - layout: 'padded' - }, - decorators: [ - Story => ( -
- - - ) - ], - excludeStories: ['TextareaTemplate'], - argTypes: { - size: { - options: [0, 1, 2], // iterator - mapping: [null, 'input-sm', 'input-lg'], // values - control: { - type: 'select', - labels: ['default', 'small', 'large'] - }, - table: { - category: 'CSS' - } - }, - block: { - description: 'full width', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - contrast: { - description: 'change input background to light gray', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - disabled: { - description: 'disabled field', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - hideWebKit: { - description: 'hide WebKit autofill icon', - control: {type: 'boolean'}, - table: { - category: 'Interactive' - } - }, - placeholder: { - type: 'string', - name: 'placeholder', - description: 'string', - table: { - category: 'HTML' - } - }, - label: { - type: 'string', - name: 'label', - description: 'string', - table: { - category: 'HTML' - } - }, - type: { - name: 'type', - type: 'string', - description: 'type', - table: { - category: 'HTML' - } - }, - id: { - name: 'id', - type: 'string', - description: 'id', - table: { - category: 'HTML' - } - }, - focusElement: { - control: {type: 'boolean'}, - description: 'set focus on element', - table: { - category: 'Interactive' - } - }, - focusAllElements: { - control: {type: 'boolean'}, - description: 'set focus on all elements for viewing in all themes', - table: { - category: 'Interactive' - } - } - } -} - -const focusMethod = function getFocus() { - // find the focusable element - var textarea = document.getElementsByTagName('textarea')[0] - // set focus on element - textarea.focus() -} - -export const TextareaTemplate = ({ - label, - type, - id, - size, - block, - placeholder, - contrast, - disabled, - hideWebKit, - focusElement, - focusAllElements -}) => ( - <> - - + + + + + ) +} + +export const ValidationSuccess = () => { + return ( + <> +
+
+
+ +
+
+ +
+

+ monalisa is available +

+
+
+ + ) +} + +export const ValidationError = () => { + return ( + <> +
+
+
+ +
+
+ +
+

+ monalisa is not available. monalisa-beep, monalisa-cyber, or monalisa87 are available. +

+
+
+ + ) +} + +export const ValidationWarning = () => { + return ( + <> +
+
+
+ +
+
+ +
+

+ 36 of maximum 39 characters entered. +

+
+
+ + ) +} + +export const FormActions = () => { + return ( + <> +
+ + +
+ + ) +} + +export const CheckboxAndRadios = () => { + return ( + <> +
+
+ +

+ This will do insanely awesome and amazing things! +

+
+
+
+
+ +
+
+ + ) +} + +export const ToggleVisibility = () => { + return ( + <> +
+
+ +
+
+ +
+
+ + ) +} + +export const RadioGroup = () => { + return ( + <> +
+
+ + + + + + +
+
+ + ) +} + +export const WithOcticons = () => { + return ( + <> +
+
+ + + + + + +
+
+ + ) +} diff --git a/docs/src/stories/deprecated-components/Header/Header.stories.mdx b/docs/src/stories/deprecated-components/Header/Header.stories.mdx new file mode 100644 index 0000000000..10639fb580 --- /dev/null +++ b/docs/src/stories/deprecated-components/Header/Header.stories.mdx @@ -0,0 +1,43 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as HeaderStories from './Header.stories' + + + +# Header + +Use the Header component to create a header that has all of its items aligned vertically with consistent horizontal spacing. + +## Header + +The `.Header` class is the wrapping class that aligns all the items properly and gives the header its dark background. Each direct child of the `.Header` component is expected to be a `.Header-item` component. The component utilizes flexbox CSS to align all these items properly and applies spacing scale margin. + + + + + +## Header-item + +All items directly under the `.Header` component should be a `.Header-item` component. Inside these components can be anything (text, forms, images...), and the `.Header-item` component will make sure these elements vertically align with each other. + +`.Header-item` elements have a built-in margin that will need to be overridden with the `mr-0` utility class for the last element in the container. We relied on the utility classes here instead of `:last-child` because the last child isn't always the item visible. On responsive pages, there's a mobile menu that gets presented to the user at smaller breakpoints. + + + + + +### Header-item--full + +The `.Header-item` element has a modifier class, `.Header-item--full`, that stretches it to fill the available space and push any remaining items to the right. + + + + + +## Header-link + +Add the `.Header-link` class to any anchor tags in the header to give them consistent styling and hover opacity. This class makes the links white, bold and 70% fade on hover. + + + + diff --git a/docs/src/stories/deprecated-components/Header/Header.stories.tsx b/docs/src/stories/deprecated-components/Header/Header.stories.tsx new file mode 100644 index 0000000000..709ad423b4 --- /dev/null +++ b/docs/src/stories/deprecated-components/Header/Header.stories.tsx @@ -0,0 +1,95 @@ +import React from 'react' + +export default { + title: 'Deprecated/Header', +} + +export const Default = () => { + return ( + <> +
+ +
+ +
+
Menu
+
+ @octocat +
+
+ + ) +} + +export const HeaderItem = () => { + return ( + <> +
+
Text item
+ +
+ +
+ +
+ @octocat +
+
+ + ) +} + +export const HeaderItemFull = () => { + return ( + <> +
+
Item 1
+ +
Item 2
+ +
Item 3
+
+ + ) +} + +export const HeaderLink = () => { + return ( + <> + + + ) +} diff --git a/docs/src/stories/deprecated-components/IssueLabel/IssueLabel.stories.mdx b/docs/src/stories/deprecated-components/IssueLabel/IssueLabel.stories.mdx new file mode 100644 index 0000000000..abe5d09bc5 --- /dev/null +++ b/docs/src/stories/deprecated-components/IssueLabel/IssueLabel.stories.mdx @@ -0,0 +1,19 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as IssueLabelStories from './IssueLabel.stories' + + + +# IssueLabel + +Issue labels are used for adding labels to issues and pull requests. They also come with emoji support. + + + + + +If an issue label needs to be bigger, add the `.IssueLabel--big` modifier. + + + + diff --git a/docs/src/stories/deprecated-components/IssueLabel/IssueLabel.stories.tsx b/docs/src/stories/deprecated-components/IssueLabel/IssueLabel.stories.tsx new file mode 100644 index 0000000000..060d6e54e7 --- /dev/null +++ b/docs/src/stories/deprecated-components/IssueLabel/IssueLabel.stories.tsx @@ -0,0 +1,31 @@ +import React from 'react' + +export default { + title: 'Deprecated/IssueLabel', +} + +export const Default = () => { + return ( + <> + Primer + bug 🐛 + help wanted + 🚂 deploy: train + + ) +} + +export const Big = () => { + return ( + <> + Primer + bug 🐛 + + help wanted + + + 🚂 deploy: train + + + ) +} diff --git a/docs/src/stories/deprecated-components/Loaders/Loaders.stories.mdx b/docs/src/stories/deprecated-components/Loaders/Loaders.stories.mdx new file mode 100644 index 0000000000..1a28c8b471 --- /dev/null +++ b/docs/src/stories/deprecated-components/Loaders/Loaders.stories.mdx @@ -0,0 +1,15 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as LoaderStories from './Loaders.stories' + + + +# Loaders + +Loaders inform users that an action is still in progress and might take a while to complete. + +Add an animated ellipsis at the end of text with ``. + + + + diff --git a/docs/src/stories/deprecated-components/Loaders/Loaders.stories.tsx b/docs/src/stories/deprecated-components/Loaders/Loaders.stories.tsx new file mode 100644 index 0000000000..ec928c7c9f --- /dev/null +++ b/docs/src/stories/deprecated-components/Loaders/Loaders.stories.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default { + title: 'Deprecated/Loaders', +} + +export const Default = () => { + return ( + <> +

+ Loading + +

+ + Loading + + + + Loading + + + + + ) +} diff --git a/docs/src/stories/deprecated-components/Markdown/Markdown.stories.tsx b/docs/src/stories/deprecated-components/Markdown/Markdown.stories.tsx new file mode 100644 index 0000000000..820331ce4e --- /dev/null +++ b/docs/src/stories/deprecated-components/Markdown/Markdown.stories.tsx @@ -0,0 +1,387 @@ +import React from 'react' + +export default { + title: 'Deprecated/Markdown', +} + +export const Default = () => { + return ( + <> +
+

+ Text can be bold, italic, or strikethrough. Links {' '} + should be blue with no underlines (unless hovered over). +

+

+ There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be + whitespace between paragraphs. There should be whitespace between paragraphs. +

+

+ There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be + whitespace between paragraphs. There should be whitespace between paragraphs. +

+
+

There should be no margin above this first sentence.

+

Blockquotes should be a lighter gray with a gray border along the left side.

+

There should be no margin below this final sentence.

+
+

Header 1

+

+ This is a normal paragraph following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork + belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet + mignon cow shoulder short ribs biltong. +

+

Header 2

+
+ This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly + porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet + mignon cow shoulder short ribs biltong. +
+

Header 3

+
+          This is a code block following a header.
+        
+

Header 4

+
    +
  • This is an unordered list following a header.
  • +
  • This is an unordered list following a header.
  • +
  • This is an unordered list following a header.
  • +
+
Header 5
+
    +
  1. This is an ordered list following a header.
  2. +
  3. This is an ordered list following a header.
  4. +
  5. This is an ordered list following a header.
  6. +
+
Header 6
+ + + + + + + + + + + + + + + + + + + + + +
WhatFollows
A tableA header
A tableA header
A tableA header
+
+

There's a horizontal rule above and below this.

+
+

Here is an unordered list:

+
    +
  • Salt-n-Pepa
  • +
  • Bel Biv DeVoe
  • +
  • Kid 'N Play
  • +
+

And an ordered list:

+
    +
  1. Michael Jackson
  2. +
  3. Michael Bolton
  4. +
  5. Michael Bublé
  6. +
+

And an unordered task list:

+
    +
  • + Create a sample markdown document +
  • +
  • + Add task lists to it +
  • +
  • + Take a vacation +
  • +
+

And a "mixed" task list:

+
    +
  • + Steal underpants +
  • +
  • ?
  • +
  • + Profit! +
  • +
+ And a nested list: +
    +
  • + Jackson 5 +
      +
    • Michael
    • +
    • Tito
    • +
    • Jackie
    • +
    • Marlon
    • +
    • Jermaine
    • +
    +
  • +
  • + TMNT +
      +
    • Leonardo
    • +
    • Michelangelo
    • +
    • Donatello
    • +
    • Raphael
    • +
    +
  • +
+

Definition lists can be used with HTML syntax. Definition terms are bold and italic.

+
+
Name
+
Godzilla
+
Born
+
1952
+
Birthplace
+
Japan
+
Color
+
Green
+
+
+

Tables should have bold headings and alternating shaded rows.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArtistAlbumYear
David BowieScary Monsters1980
PrincePurple Rain1982
Beastie BoysLicense to Ill1986
Janet JacksonRhythm Nation 18141989
+

If a table is too wide, it should condense down and/or scroll horizontally.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArtistAlbumYearLabelSongs
David BowieScary Monsters1980RCA Records + It's No Game (No. 1), Up the Hill Backwards, Scary Monsters (And Super Creeps), Ashes to Ashes, Fashion, + Teenage Wildlife, Scream Like a Baby, Kingdom Come, Because You're Young, It's No Game (No. 2) +
PrincePurple Rain1982Warner Brothers Records + Let's Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I + Would Die 4 U, Baby I'm a Star, Purple Rain +
Beastie BoysLicense to Ill1986Def Jam + Rhymin & Stealin, The New Style, She's Crafty, Posse in Effect, Slow Ride, Girls, Fight for Your + Right, No Sleep till Brooklyn, Paul Revere, "Hold It Now, Hit It", Brass Monkey, Slow and Low, Time to + Get Ill +
Janet JacksonRhythm Nation 18141989A&M + Interlude: Pledge, Rhythm Nation, Interlude: T.V., State of the World, Interlude: Race, The Knowledge, + Interlude: Let's Dance, Miss You Much, Interlude: Come Back, Love Will Never Do (Without You), Livin' in + a World (They Didn't Make), Alright, Interlude: Hey Baby, Escapade, Interlude: No Acid, Black Cat, + Lonely, Come Back to Me, Someday Is Tonight, Interlude: Livin'...In Complete Darkness +
+
+

+ Code snippets like var foo = "bar"; can be shown inline. +

+

+ Also, this should vertically align{' '} + + with this + {' '} + and this. +

+

Code can also be shown in a block element.

+
+          var foo = "bar";
+        
+

Code can also use syntax highlighting.

+
+          var foo = "bar";
+        
+
+          
+            Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This
+            line should be long enough to demonstrate this.
+          
+        
+
+          
+            var foo = "The same thing is true for code with syntax highlighting. A single line of code should
+            horizontally scroll if it is really long.";
+          
+        
+

Inline code inside table cells should still be distinguishable.

+ + + + + + + + + + + + + + + + + +
LanguageCode
JavasScript + var foo = "bar"; +
Ruby + foo = "bar" +
+
+

+ The samp HTML element is used to enclose inline text which represents sample (or quoted) output + from a computer program. Here an example of an error message: File not found +

+
+

Small images should be shown at their actual size.

+

+ +

+

Large images should always scale down and fit in the content container.

+

+ +

+

+ Here's a simple footnote, + + + 1 + + {' '} + and here's a longer one. + + + 2 + + +

+
+

+ Footnotes +

+
    +
  1. +

    + This is the first footnote.{' '} + + + ↩ + + +

    +
  2. +
  3. +

    Here's one with multiple paragraphs and code.

    +

    Indent paragraphs to include them in the footnote.

    +

    + my code +

    +

    + Add as many paragraphs as you like.{' '} + + + ↩ + + +

    +
  4. +
+
+
+          This is the final element on the page and there should be no margin below this.
+        
+
+ + ) +} diff --git a/docs/src/stories/deprecated-components/Marketing/Marketing.stories.mdx b/docs/src/stories/deprecated-components/Marketing/Marketing.stories.mdx new file mode 100644 index 0000000000..0388cbf762 --- /dev/null +++ b/docs/src/stories/deprecated-components/Marketing/Marketing.stories.mdx @@ -0,0 +1,33 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as MarketingStories from './Marketing.stories' + + + +# Marketing links + +Marketing links can be produced by combining the base class `link-mktg` with a set of modifier classes to control the size and color. + + + + + +## Link sizes + +The marketing link size is defined with utility classes and come in large (`.f3-mktg`) and small (`.f4-mktg`): + +## Link with emphasis + +Add class `link-emphasis-mktg` to the link, to give it a pale underline, that will fill up on hover. + + + + + +## Link colors + +The link color is controlled with the [Primer color classes](/utilities/colors), while the symbol and underline styling will follow: + + + + diff --git a/docs/src/stories/deprecated-components/Marketing/Marketing.stories.tsx b/docs/src/stories/deprecated-components/Marketing/Marketing.stories.tsx new file mode 100644 index 0000000000..24aa4f8abf --- /dev/null +++ b/docs/src/stories/deprecated-components/Marketing/Marketing.stories.tsx @@ -0,0 +1,137 @@ +import React from 'react' + +export default { + title: 'Deprecated/Marketing', +} + +export const Link = () => { + return ( + <> + + Call to action + + + + + + + Call to action + + + + + + + ) +} + +export const Hover = () => { + return ( + <> + + Call to action + + + + + + + ) +} +Hover.parameters = {pseudo: {hover: true}} + +export const LinkEmphasis = () => { + return ( + <> + + Call to action + + + + + + + ) +} + +export const LinkColors = () => { + return ( + <> + + Call to action + + + + + + + + Call to action + + + + + + + ) +} diff --git a/docs/src/stories/deprecated-components/Pagination/Pagination.stories.mdx b/docs/src/stories/deprecated-components/Pagination/Pagination.stories.mdx new file mode 100644 index 0000000000..a0dbeb4e02 --- /dev/null +++ b/docs/src/stories/deprecated-components/Pagination/Pagination.stories.mdx @@ -0,0 +1,32 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as PaginationStories from './Pagination.stories' + + + +# Pagination + +Use the pagination component to apply button styles to a connected set of links that go to related pages (for example, previous, next, or page numbers). + +## Previous/next pagination + +You can make a very simple pagination container with just the Previous and Next buttons. Add the `aria-disabled="true"` attribute to the `Previous` button if there isn't a preceding page, or to the `Next` button if there isn't a succeeding page. + + + + + +## Numbered pagination + +For pagination across multiple pages, make sure it's clear to the user where they are in a set of pages. + +To do this, add anchor links to the `pagination` element. Previous and Next buttons should always be present. Add the `aria-disabled="true"` attribute to the Previous button if you're on the first page. Apply the `aria-current="page"` attribute to the current numbered page. + +As always, make sure to include the appropriate `aria` attributes to make the element accessible. + +- Add `aria-label="Pagination"` to the `paginate-container` element. +- Add `aria-label="Page X"` to each anchor link. + + + + diff --git a/docs/src/stories/deprecated-components/Pagination/Pagination.stories.tsx b/docs/src/stories/deprecated-components/Pagination/Pagination.stories.tsx new file mode 100644 index 0000000000..18bb74c62c --- /dev/null +++ b/docs/src/stories/deprecated-components/Pagination/Pagination.stories.tsx @@ -0,0 +1,54 @@ +import React from 'react' + +export default { + title: 'Deprecated/Pagination', +} + +export const Default = () => { + return ( + <> + + + ) +} + +export const Numbered = () => { + return ( + + ) +} diff --git a/docs/src/stories/deprecated-components/SelectMenu/SelectMenu.stories.mdx b/docs/src/stories/deprecated-components/SelectMenu/SelectMenu.stories.mdx new file mode 100644 index 0000000000..76c470d5fe --- /dev/null +++ b/docs/src/stories/deprecated-components/SelectMenu/SelectMenu.stories.mdx @@ -0,0 +1,169 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as SelectMenuStories from './SelectMenu.stories' + + + +# SelectMenu + +Please note that this is a newer version and uses the `.SelectMenu` class instead of the deprecated select menu class. Check the migration guide to make sure your app is up to date. + +The `SelectMenu` component provides advanced support for navigation, filtering, and more. Any menu can make use of JavaScript-enabled live filtering, selected states, tabbed lists, and keyboard navigation with a bit of markup. + +## Basic example + +Use a `
` element to toggle the select menu. The `` element can be styled in many ways. In the example below it's a `.btn`. + + + + + +Add a `.SelectMenu-header` to house a clear title and a close button. Note that the close button is only shown on narrow screens (mobile). + +## Right aligned + +In case the select menu should be aligned to the right, use `SelectMenu right-0`. + + + + + +## Selected state + +If the `SelectMenu` should show a check icon for selected items, use the `SelectMenu-icon SelectMenu-icon--check` classes. It will make the check icon show when `aria-checked="true"` is set. + + + + + +## Borderless + +Use the `.SelectMenu-list--borderless` modifier to remove the borders between list items. Note: It's better to keep the borders if a list contains items with multiple lines of text. It will make it easier to see where the items start and end. + + + + + +## Header + +Add a `.SelectMenu-header` at the top to house a clear title and a close button. + + + + + +## List items + +The list of items is arguably the most important subcomponent within the menu. Build them out of anchors, buttons, or just about any [interactive content](http://w3c.github.io/html/dom.html#interactive-content). List items are also customizable with options for avatars, additional icons, and multiple lines of text. Use utility classes in case more custom styling is needed. + + + + + +## Divider + +The select menu's list can be divided into multiple parts by adding a `.SelectMenu-divider`. It can be a `
` with text/content. Or just an `
` to add a visual separator. + +Dividers are also supported when using the `.SelectMenu-list--borderless` modifier. + + + + + +## Footer + +Use a `.SelectMenu-footer` at the bottom for additional information. As a side effect it can greatly improve the scrolling performance because the list doesn't need to be repainted due to the rounded corners. + + + + + +## Filter + +If the list is expected to get long, consider adding a `.SelectMenu-filter` input. Be sure to also include the `.SelectMenu--hasFilter` modifier class. On mobile devices it will add a fixed height and anchor the select menu to the top of the screen. This makes sure the filter input stays at the same position while typing. + + + + + +## Tabs + +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. + + + + + +## Message + +A `SelectMenu-message` can be used to show different kind of messages to a user. Use utility classes to further style the message. + + + + + +## Loading + +When fetching large lists, consider showing a `.SelectMenu-loading` animation. + + + + + +## Disabled + +To disable a list item, use the `disabled` attribute for ` + + +
+ +
+``` + +If loading content should be deferred, use the [``](https://github.com/github/details-menu-element) element: + +```erb + +
+ + <%= octicon("octoface", class: "anim-pulse", :height => 32) %> + +
+
+``` + +It will add a pulsing "octoface" icon while the content is loading. diff --git a/docs/src/stories/deprecated-components/SelectMenu/SelectMenu.stories.tsx b/docs/src/stories/deprecated-components/SelectMenu/SelectMenu.stories.tsx new file mode 100644 index 0000000000..927e251049 --- /dev/null +++ b/docs/src/stories/deprecated-components/SelectMenu/SelectMenu.stories.tsx @@ -0,0 +1,843 @@ +import React from 'react' + +export default { + title: 'Deprecated/SelectMenu', +} + +export const Default = () => { + return ( + <> +
+ + Choose an item + +
+
+
+ + + +
+
+
+
+ +
+
+ + ) +} + +export const RightAligned = () => { + return ( + <> +
+
+ + Choose an item + +
+
+
+ + + +
+
+
+
+
+ +
+
+ + ) +} + +export const SelectedState = () => { + return ( + <> +
+ + Choose an item + +
+
+
+ + + + + +
+
+
+
+ +
+
+ + ) +} + +export const Borderless = () => { + return ( + <> +
+ + Choose an item + +
+
+
+ + + +
+
+
+
+ +
+
+ + ) +} + +export const Header = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+ + + +
+
+
+
+ +
+
+ + ) +} + +export const ListItems = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+ + + + + + +
+
+
+
+ +
+
+ + ) +} + +export const Divider = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+ + +
More options
+ + +
+ + +
+
+
+
+ +
+
+ + ) +} + +export const Footer = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+ + + + + +
+
Footer
+
+
+
+ +
+
+ + ) +} + +export const Filter = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
Showing 25 of 25
+
+
+
+ +
+
+ + ) +} + +export const Tabs = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+ +
+ +
+ + + + + +
+ +
Showing 5 of 5
+
+
+
+
+
+ + ) +} + +export const Message = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+
Message goes here
+ + + +
+
+
+
+
+
+ + ) +} + +export const Loading = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+
+ +
+
+
Loading...
+
+
+
+
+
+ + ) +} + +export const Disabled = () => { + return ( + <> +
+ + Choose an item + +
+
+
+ + + + Item 3 + + + Item 4 (disabled) + +
+
+
+
+
+
+ + ) +} + +export const BlankSlate = () => { + return ( + <> +
+ + Choose an item + +
+
+
+

Title

+ +
+
+
+ +

No repositories

+

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

+ +
+
+
+
+
+
+
+ + ) +} diff --git a/docs/src/stories/deprecated-components/SideNav/SideNav.stories.mdx b/docs/src/stories/deprecated-components/SideNav/SideNav.stories.mdx new file mode 100644 index 0000000000..f3754312c9 --- /dev/null +++ b/docs/src/stories/deprecated-components/SideNav/SideNav.stories.mdx @@ -0,0 +1,34 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as SideNavStories from './SideNav.stories' + + + +# SideNav + +The Side Nav is a vertical list of navigational links, typically used on the left side of a page. For maximum flexibility, **Side Nav elements have no default width or positioning**. We suggest using [column grid](../utilities/grid) classes or an inline `width` style for sizing, and [flexbox utilities](../utilities/flexbox) for positioning alongside content. + +- You can use a **border** if the parent element doesn't have it already. +- Add `aria-current="page"` to show a link as selected. Selected button elements in tab-like UIs should instead have `aria-selected="true"`. + + + + + +Different kind of content can be added inside a Side Nav item. Use utility classes to further style them if needed. + + + + + +The `.SideNav-subItem` is an alternative, more lightweight version without borders and more condensed. It can be used stand-alone. + + + + + +Or also appear nested, as a sub navigation. Use margin/padding utility classes to add indentation. + + + + diff --git a/docs/src/stories/deprecated-components/SideNav/SideNav.stories.tsx b/docs/src/stories/deprecated-components/SideNav/SideNav.stories.tsx new file mode 100644 index 0000000000..ffff0f5f00 --- /dev/null +++ b/docs/src/stories/deprecated-components/SideNav/SideNav.stories.tsx @@ -0,0 +1,180 @@ +import React from 'react' + +export default { + title: 'Deprecated/SideNav', +} + +export const Default = () => { + return ( + <> + + + ) +} + +export const Options = () => { + return ( + <> + + + ) +} + +export const SubItem = () => { + return ( + <> + + + ) +} + +export const Nested = () => { + return ( + <> + + + ) +} diff --git a/docs/src/stories/deprecated-components/SubNav/SubNav.stories.mdx b/docs/src/stories/deprecated-components/SubNav/SubNav.stories.mdx new file mode 100644 index 0000000000..02b34d64f4 --- /dev/null +++ b/docs/src/stories/deprecated-components/SubNav/SubNav.stories.mdx @@ -0,0 +1,25 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as SubNavStories from './SubNav.stories' + + + +# SubNav + +`.subnav` is navigation that is typically used when on a dashboard type interface with another set of navigation above it. This helps distinguish navigation hierarchy. + + + + + +You can have `subnav-search` in the subnav bar. + + + + + +You can also use a `subnav-search-context` to display search help in a select menu. + + + + diff --git a/docs/src/stories/deprecated-components/SubNav/SubNav.stories.tsx b/docs/src/stories/deprecated-components/SubNav/SubNav.stories.tsx new file mode 100644 index 0000000000..8aa0590015 --- /dev/null +++ b/docs/src/stories/deprecated-components/SubNav/SubNav.stories.tsx @@ -0,0 +1,115 @@ +import React from 'react' + +export default { + title: 'Deprecated/SubNav', +} + +export const Default = () => { + return ( + <> + + + ) +} + +export const Search = () => { + return ( + <> +
+ +
+ + +
+
+ + ) +} + +export const SearchContext = () => { + return ( + <> + +
+
+ +
+
+ + +
+
+ + ) +} diff --git a/docs/src/stories/deprecated-components/Toast/Toast.stories.mdx b/docs/src/stories/deprecated-components/Toast/Toast.stories.mdx new file mode 100644 index 0000000000..09796b5076 --- /dev/null +++ b/docs/src/stories/deprecated-components/Toast/Toast.stories.mdx @@ -0,0 +1,77 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as ToastStories from './Toast.stories' + + + +# Toast + +Toasts are used to show live, time-sensitive feedback to users. + +## Default + +To create a default toast, use `.Toast`. Always use the `info` icon for default messages. + + + + + +The Toast content is formattable. We recommend keeping your message under 140 characters. + +## Variations + +Use the success, warning, and error modifiers to communicate different states. + +Always use the `check` octicon for success states. + + + + + +Always use the `alert` octicon for warning states. + + + + + +Always use the `stop` octicon for error states. + + + + + +## Toast with dismiss + +Use `.Toast-dismissButton` to allow a user to explicitly dismiss a Toast. + + + + + +## Toast with link + +Include a link to allow users to take actions within a Toast. + + + + + +## Toast animation in + +The `Toast--animateIn` and `Toast--animateOut` modifier classes can be used to animate the toast in and out from the bottom. + + + + + +## Toast with loading animation + +Add the `Toast--spinner` modifier class on the `Toast-icon` `svg` to communicate a loading state. + + + + + +## Toast position + +Use the `position-fixed bottom-0 left-0` utility classes on a wrapper element to position Toasts at the **bottom left** of the viewport. diff --git a/docs/src/stories/deprecated-components/Toast/Toast.stories.tsx b/docs/src/stories/deprecated-components/Toast/Toast.stories.tsx new file mode 100644 index 0000000000..1e56322ee8 --- /dev/null +++ b/docs/src/stories/deprecated-components/Toast/Toast.stories.tsx @@ -0,0 +1,195 @@ +import React from 'react' + +export default { + title: 'Deprecated/Toast', +} + +export const Default = () => { + return ( + <> +
+
+ + + + Toast message goes here +
+
+ + ) +} + +export const Success = () => { + return ( + <> +
+
+ + + + Success message goes here. +
+
+ + ) +} + +export const Alert = () => { + return ( + <> +
+
+ + + + Warning message goes here. +
+
+ + ) +} + +export const Error = () => { + return ( + <> +
+
+ + + + Error message goes here +
+
+ + ) +} + +export const Dismiss = () => { + return ( + <> +
+
+ + + + This toast is dismissable. + +
+
+ + ) +} + +export const WithLink = () => { + return ( + <> +
+
+ + + + + Toast message goes hereAction. + +
+
+ + ) +} + +export const AnimationIn = () => { + return ( + <> +
+
+ + + + Toast message goes here. +
+
+ + ) +} + +export const Loading = () => { + return ( + <> +
+
+ + + + + + + Toast message goes here. +
+
+ + ) +} + +export const Position = () => { + return ( + <> +
+
+
+ + + + Toast message goes here. +
+
+
+ + ) +} diff --git a/docs/src/stories/deprecated-components/Tooltip/Tooltip.stories.mdx b/docs/src/stories/deprecated-components/Tooltip/Tooltip.stories.mdx new file mode 100644 index 0000000000..5b4b6bf02e --- /dev/null +++ b/docs/src/stories/deprecated-components/Tooltip/Tooltip.stories.mdx @@ -0,0 +1,55 @@ +import {Meta, Story, Canvas} from '@storybook/addon-docs' + +import * as TooltipStories from './Tooltip.stories' + + + +# Tooltip + +Please note that the `.tooltipped` component is **deprecated**. We recommend using the [Tooltip component](https://primer.style/view-components/components/alpha/tooltip) instead. + +Add tooltips built entirely in CSS to appropriate elements. + +## Implementation and accessibility + +Tooltips as a UI pattern should be our last resort for conveying information because it is hidden by default and often with zero or little visual indicator of its existence. + +Before adding a tooltip, please consider: Is this information essential and necessary\* Can the UI be made clearer? Can the information be shown on the page by default? And check out [alternatives to Tooltips](https://primer.style/design/accessibility/tooltip-alternatives) to explore your options. + +### Attention + +- **Never** use tooltips on static elements. They should only be used on interactive elements, because users cannot tab-focus into static elements, which may make the content inaccessible for keyboard-only users and screen readers. +- we use `aria-label` for tooltip contents, because it is crucial that they are accessible to screen reader users. However, `aria-label` **replaces** the text content of an element in screen readers, so only use `.tooltipped` on elements with no existing text content such as an icon-only button. +- Tooltip classes will conflict with Octicon styles, and as such, must be applied to the parent element instead of the icon. + +## Tooltip direction + +Specify the direction of a tooltip with north, south, east, and west directions: + + + + + +## Tooltip alignment + +Align tooltips to the left or right of an element, combined with a directional class to specify north or south. Use a modifier of `1` or `2` to choose how much the tooltip's arrow is indented. + + + + + +## Tooltips with multiple lines + +Use `.tooltipped-multiline` when you have long content. This style has some limitations: you cannot pre-format the text with newlines, and tooltips are limited to a max-width of `250px`. + + + + + +## Tooltips with no delay + +By default the tooltips have a slight delay before appearing. This is to keep multiple tooltips in the UI from being distracting. There is a `.tooltipped-no-delay` modifier class you can use to override this. + + + + diff --git a/docs/src/stories/deprecated-components/Tooltip/Tooltip.stories.tsx b/docs/src/stories/deprecated-components/Tooltip/Tooltip.stories.tsx new file mode 100644 index 0000000000..485a9265f8 --- /dev/null +++ b/docs/src/stories/deprecated-components/Tooltip/Tooltip.stories.tsx @@ -0,0 +1,177 @@ +import React from 'react' + +export default { + title: 'Deprecated/Tooltip', +} + +export const Default = () => { + return ( + <> +
+ + + +
+
+ + +
+
+ + + +
+ + ) +} + +export const Alignment = () => { + return ( + <> +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + ) +} + +export const MultiLine = () => { + return ( + <> +
+ +
+ + ) +} + +export const NoDelay = () => { + return ( + <> +
+ +
+ + ) +} diff --git a/docs/src/stories/helpers/ColorBlock.jsx b/docs/src/stories/helpers/ColorBlock.jsx deleted file mode 100644 index ab45cc53da..0000000000 --- a/docs/src/stories/helpers/ColorBlock.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' - -const ColorBlock = ({backgroundColor, showValueLabel}) => { - return ( -
-
- {showValueLabel &&
{backgroundColor}
} -
- ) -} - -ColorBlock.propTypes = { - backgroundColor: PropTypes.string, - showValueLabel: PropTypes.bool -} - -ColorBlock.defaultProps = { - backgroundColor: null, - showValueLabel: false -} - -export default ColorBlock diff --git a/docs/src/stories/helpers/ConditionalWrapper.jsx b/docs/src/stories/helpers/ConditionalWrapper.jsx deleted file mode 100644 index 98ed8d4bb9..0000000000 --- a/docs/src/stories/helpers/ConditionalWrapper.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react' - -// reference https://gist.github.com/kitze/23d82bb9eb0baabfd03a6a720b1d637f - -const ConditionalWrapper = ({condition, wrap, children}) => (condition ? wrap(children) : children) - -export default ConditionalWrapper diff --git a/docs/src/stories/helpers/code-snippet-html-helper.js b/docs/src/stories/helpers/code-snippet-html-helper.js deleted file mode 100644 index ae755a358b..0000000000 --- a/docs/src/stories/helpers/code-snippet-html-helper.js +++ /dev/null @@ -1,13 +0,0 @@ -import {renderToStaticMarkup} from 'react-dom/server' -import {AllHtmlEntities} from 'html-entities' -import prettier from 'prettier' -import HTMLParser from 'prettier/parser-html' -const entities = new AllHtmlEntities() - -export default story => - prettier.format(entities.decode(renderToStaticMarkup(story())), { - parser: 'html', - plugins: [HTMLParser], - htmlWhitespaceSensitivity: 'ignore', - bracketSameLine: 'false' - }) diff --git a/docs/src/stories/helpers/storybook-styles.scss b/docs/src/stories/helpers/storybook-styles.scss deleted file mode 100644 index 70f9f926e0..0000000000 --- a/docs/src/stories/helpers/storybook-styles.scss +++ /dev/null @@ -1,21 +0,0 @@ -// color blocks - -.colorBlockWrap { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 1rem; -} - -.colorBlockItem { - aspect-ratio: 1/1; - width: 100px; -} - -.toc { - list-style: none !important; - padding: 0 !important; - li { - margin-left: 0 !important; - } -} diff --git a/docs/src/stories/helpers/useToggle.jsx b/docs/src/stories/helpers/useToggle.jsx deleted file mode 100644 index a38dfcb2c4..0000000000 --- a/docs/src/stories/helpers/useToggle.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -export default function useToggle(initialValue = false) { - const [value, setValue] = React.useState(initialValue) - const toggle = React.useCallback(() => { - setValue(v => !v) - }, []) - return [value, toggle] -} diff --git a/docs/src/stories/patterns/FocusStyles.stories.jsx b/docs/src/stories/patterns/FocusStyles.stories.jsx deleted file mode 100644 index 7b3dd2f747..0000000000 --- a/docs/src/stories/patterns/FocusStyles.stories.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import {ButtonTemplate} from '../components/Button/Button.stories.jsx' -import {CheckboxTemplate} from '../components/Forms/Checkbox.stories.jsx' -import {InputTemplate} from '../components/Forms/Input.stories.jsx' -import {SelectTemplate} from '../components/Forms/Select.stories.jsx' -import {TextareaTemplate} from '../components/Forms/Textarea.stories.jsx' -import {LinkTemplate} from '../components/Link/Link.stories.jsx' -import {MarketingButtonTemplate} from '../components/Marketing/MarketingButton.stories.jsx' -import {MarketingLinkTemplate} from '../components/Marketing/MarketingLink.stories.jsx' -import {TabNavTemplate} from '../components/Navigation/TabNav.stories.jsx' -import {TabNavItemTemplate} from '../components/Navigation/TabNavItem.stories.jsx' - -export default { - title: 'Patterns/FocusStyles', - layout: 'padded' -} - -export const FocusStyles = ({}) => ( -
-
- - - - - - - - - `} - /> - - - - - - -
-
- - - - - - - - Link with no CSS class - - -
-
- - - - -
- -
:target styles
- -
-) diff --git a/docs/src/stories/playground/ColorPlayground.stories.jsx b/docs/src/stories/playground/ColorPlayground.stories.jsx deleted file mode 100644 index 0268f67067..0000000000 --- a/docs/src/stories/playground/ColorPlayground.stories.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import ColorBlock from '../helpers/ColorBlock' -import DarkColorblind from '@primer/primitives/dist/json/colors/dark_colorblind.json' -import DarkTritanopia from '@primer/primitives/dist/json/colors/dark_tritanopia.json' -import DarkDimmed from '@primer/primitives/dist/json/colors/dark_dimmed.json' -import DarkHighContrast from '@primer/primitives/dist/json/colors/dark_high_contrast.json' -import Dark from '@primer/primitives/dist/json/colors/dark.json' -import Light from '@primer/primitives/dist/json/colors/light.json' -import LightColorblind from '@primer/primitives/dist/json/colors/light_colorblind.json' -import LightTritanopia from '@primer/primitives/dist/json/colors/light_tritanopia.json' - -/* -* Welcome to the Primer CSS Playground! - -* Use the code snippets from [prototyping guide](./Prototyping.stories.mdx) for setting up controls and conditional logic - -* Uncomment any code that you need, and feel free to delete whatever gets in your way - -* argTypes are optional for prototyping -*/ - -export default { - title: 'Prototypes/Color', - // layout: 'padded', // add padding around frame - layout: 'fullwidth', - excludeStories: ['ColorPlaygroundTemplate'], - // optional argTypes - argTypes: { - backgroundColor: { - name: 'color', - control: 'color', - description: 'use with an inline style tag to access a colorpicker control' - } - } -} - -const ColorPlaygroundTemplate = ({backgroundColor}) => { - return ( -
- - -
- ) -} - -export const Color = ColorPlaygroundTemplate.bind({}) -Color.args = { - backgroundColor: '#000000' -} -Color.parameters = { - colorPalettes: { - palettes: [ - { - name: 'dark_colorblind', - palette: DarkColorblind - }, - { - name: 'dark_tritanopia', - palette: DarkTritanopia - }, - { - name: 'dark_dimmed', - palette: DarkDimmed - }, - { - name: 'dark_high_contrast', - palette: DarkHighContrast - }, - { - name: 'dark', - palette: Dark - }, - { - name: 'light', - palette: Light - }, - { - name: 'light_colorblind', - palette: LightColorblind - }, - { - name: 'light_tritanopia', - palette: LightTritanopia - } - ] - } -} diff --git a/docs/src/stories/playground/Playground.stories.jsx b/docs/src/stories/playground/Playground.stories.jsx deleted file mode 100644 index f5443dfda6..0000000000 --- a/docs/src/stories/playground/Playground.stories.jsx +++ /dev/null @@ -1,121 +0,0 @@ -import React from 'react' -import clsx from 'clsx' -import DarkColorblind from '@primer/primitives/dist/json/colors/dark_colorblind.json' -import DarkTritanopia from '@primer/primitives/dist/json/colors/dark_tritanopia.json' -import DarkDimmed from '@primer/primitives/dist/json/colors/dark_dimmed.json' -import DarkHighContrast from '@primer/primitives/dist/json/colors/dark_high_contrast.json' -import Dark from '@primer/primitives/dist/json/colors/dark.json' -import Light from '@primer/primitives/dist/json/colors/light.json' -import LightColorblind from '@primer/primitives/dist/json/colors/light_colorblind.json' -import LightTritanopia from '@primer/primitives/dist/json/colors/light_tritanopia.json' -// import useToggle from '../helpers/useToggle.jsx' -// import ColorBlock from '../helpers/ColorBlock' -// import { StoryTemplateName } from './OtherStoryFile.stories' // import stories for component compositions - -/* -* Welcome to the Primer CSS Playground! - -* Use the code snippets from [prototyping guide](./Prototyping.stories.mdx) for setting up controls and conditional logic - -* Uncomment any code that you need, and feel free to delete whatever gets in your way - -* argTypes are optional for prototyping -*/ - -export default { - title: 'Prototypes/Playground', - // layout: 'padded', // add padding around frame - layout: 'fullwidth', - excludeStories: ['PlaygroundTemplate'], - - // optional argType examples below - argTypes: { - booleanExample: { - control: {type: 'boolean'}, - description: 'true/false toggle to controls' - }, - radioExample: { - options: ['string1', 'string2', 'string3', 'string4'], - control: { - type: 'inline-radio' - }, - description: 'radio buttons mapping to strings (example: use for variant class names)' - }, - stringExample: { - name: 'stringExample', - type: 'string', - description: 'text box control' - }, - slot: { - description: 'creates a slot for children' - }, - backgroundColor: { - name: 'color', - control: 'color', - description: 'use with an inline style tag to access a colorpicker control' - } - } -} - -// Prototype within PlaygroundTemplate -// delete argTypes between ({ here }) if not using -export const PlaygroundTemplate = ({booleanExample, radioExample, stringExample, slot, backgroundColor}) => { - return ( - <> -
Your prototype here!
- - ) -} - -export const Playground = PlaygroundTemplate.bind({}) -// Set default values for Playground story here -Playground.args = { - // backgroundColor: '' - // stringExample: 'Default text', - // booleanExample: false - // example: how to use args to set slot content - // slot: ( - // <> - // - // - // ) -} -// access color primitives from the paintbrush icon in the toolbar -Playground.parameters = { - colorPalettes: { - palettes: [ - { - name: 'dark_colorblind', - palette: DarkColorblind - }, - { - name: 'dark_tritanopia', - palette: DarkTritanopia - }, - { - name: 'dark_dimmed', - palette: DarkDimmed - }, - { - name: 'dark_high_contrast', - palette: DarkHighContrast - }, - { - name: 'dark', - palette: Dark - }, - { - name: 'light', - palette: Light - }, - { - name: 'light_colorblind', - palette: LightColorblind - }, - { - name: 'light_tritanopia', - palette: LightTritanopia - } - ] - } -} diff --git a/docs/src/stories/playground/Prototyping.stories.mdx b/docs/src/stories/playground/Prototyping.stories.mdx deleted file mode 100644 index 9b96914a55..0000000000 --- a/docs/src/stories/playground/Prototyping.stories.mdx +++ /dev/null @@ -1,392 +0,0 @@ -import {Meta} from '@storybook/addon-docs' - - - -# Primer CSS Playground - -The Playground file contains an empty story configured to promote quick design prototyping with Primer CSS. It can be used with or without controls/args, and there are no rules! Work directly in the Playground file for temporary drafting and collaborating. If what you're building is more permanent, create a folder under Components or Patterns and move your work there. - -Use this guide as a reference for code snippets, Storybook controls, and configuring conditional logic for interactive prototypes - -### On this page - - - -### CSS class syntax - -```jsx -// Ways to combine multiple CSS classes -// simple Primer classes -
- -// React/jsx syntax -
- -// conditionally add arg string as css class -
- -// conditionally set css class if arg is true/false (use !booleanExample for false) -
-``` - -### Importing other stories - -```jsx -import {StoryTemplateName} from './OtherStoryFile.stories' - -// import existing args from story - - -// optional: set new args - -``` - -### Conditional logic using Storybook controls - -Storybook controls can be used to mock interaction, state, and variants in a prototype. These are optional for prototyping, but can come in handy if you need a way to toggle state without writing custom javascript. - -The following examples show each Storybook argType available and a few ways to use them. - -#### Boolean (true/false) - -```jsx -// YourStory.stories.jsx -export default { - title: 'Prototypes/Playground', - argTypes: { - booleanExample: { - control: {type: 'boolean'}, - description: 'true/false toggle to controls' - } - } -} - -export const PlaygroundTemplate = ({booleanExample}) => { - return ( - // render markup if true or !false - {booleanExample &&
} - {!booleanExample &&
} - - // render css class 'true-class' if true else 'false-class' - // can also be undefined if false -
-
- - // set html attribute - -
- ) -} -``` - -### Execute function if boolean is true - -```jsx -// YourStory.stories.jsx -export default { - title: 'Prototypes/Playground', - argTypes: { - focusElement: { - control: {type: 'boolean'}, - description: 'set focus on element', - table: { - category: 'Interactive' - } - } - } -} - -// only one element can be focused at a time -const focusMethod = function getFocus() { - // find the focusable element - var button = document.getElementsByTagName('button')[0] - // set focus on element - button.focus() -} - -export const PlaygroundTemplate = ({focusElement}) => { - return ( - <> - - {focusElement && focusMethod()} - - ) -} -``` - -#### Radio options - -`inline-radio` type control is great for setting CSS class variants on a component when multiple class options exist. - -```jsx -// YourStory.stories.jsx -export default { - title: 'Prototypes/Playground', - argTypes: { - radioExample: { - options: ['string1', 'string2', 'string3', 'string4'], - control: { - type: 'inline-radio' - }, - description: 'radio buttons mapping to strings (example: use for variant class names)' - } - } -} - -export const PlaygroundTemplate = ({radioExample}) => { - return ( - // render css class from options -
- ) -} -``` - -#### String - -```jsx -// YourStory.stories.jsx -export default { - title: 'Prototypes/Playground', - argTypes: { - stringExample: { - name: 'stringExample', - type: 'string', - description: 'text box control' - }, - } -} - -export const PlaygroundTemplate = ({stringExample}) => { - return ( - // text -

{stringExample}

- - // id -
- - // octicon container - - ) -} -``` - -#### Slots - -```jsx -// YourStory.stories.jsx -export default { - title: 'Prototypes/Playground', - argTypes: { - slot: { - description: 'creates a slot for children' - } - } -} - -export const PlaygroundTemplate = ({slot}) => { - return ( - // creates a slot for markup or other components -

{slot}

- ) -} -``` - -### Interactive prototyping - -Sometimes you may want to prototype interactions without relying on Storybook controls. One example of this is rendering a `button` that toggles an overlay to open. You can achieve this with a `boolean` control, but in this case you want to be able to click the button in the prototype (just like an interactive prototype in Figma) - -#### Collapse/expand - -```jsx -// import the useToggle React hook -import useToggle from '../helpers/useToggle.jsx' - -export const PlaygroundTemplate = ({}) => { - const [isCollapsed, itemIsCollapsed] = useToggle() - return ( - <> - -
- - ) -} -``` - -#### Open/close - -```jsx -// import the useToggle React hook -import useToggle from '../helpers/useToggle.jsx' - -export const PlaygroundTemplate = ({}) => { - const [isOpen, itemIsOpen] = useToggle() - return ( - <> -
- More -
Hidden text
-
- - ) -} -``` - -#### HTML attribute - -Toggle any HTML attribute, like `aria-etc`, `checked`, `hidden`, etc. - -```jsx -// import the useToggle React hook -import useToggle from '../helpers/useToggle.jsx' - -export const PlaygroundTemplate = ({}) => { - const [isDisabled, itemIsDisabled] = useToggle() - return ( - <> - - - - ) -} -``` - -#### CSS class - -Toggle any CSS class to show interaction and/or animation - -```jsx -// import the useToggle React hook -import useToggle from '../helpers/useToggle.jsx' - -export const PlaygroundTemplate = ({}) => { - const [isRotating, itemIsRotating] = useToggle() - return ( - <> - - - - - - ) -} -``` - -### Working with color - -Stories have access to all distributed colors from Primer Primitives. Here are some ways you might like to utilize Storybook for testing and prototyping. - -#### View all themes - -In the Theme toolbar menu, selecting "all" will render the story in every theme. This gives you a quick overview of how color primitives interact in each theme, and is especially helpful for checking contrast ratios. - -#### Access the Storybook colorpicker - -Storybook includes a colorpicker control that may be useful for tweaking existing colors or prototyping something totally new. - -By setting the `backgroundColor`, the component also has access to the Primer Primitives color picker. Open the toolbar menu by clicking the paintbrush, and an option to replace `backgroundColor` should show up. From there, select a primitive from a given theme. - -```jsx -// YourStory.stories.jsx -export default { - title: 'Prototypes/Playground', - argTypes: { - backgroundColor: { - name: 'color', - control: 'color', - description: 'use with an inline style tag to access a colorpicker control' - } - } -} - -export const PlaygroundTemplate = ({backgroundColor}) => { - return
-} -``` - -#### ColorBlock component - -`ColorBlock` is a simple helper component that renders a square, intended to be used for quickly showing a block of color. - -```jsx -// YourStory.stories.jsx -import ColorBlock from '../helpers/ColorBlock' - -export default { - title: 'Prototypes/Playground', - argTypes: { - // optional arg - backgroundColor: { - name: 'color', - control: 'color', - description: 'use with an inline style tag to access a colorpicker control' - } - } -} - -export const PlaygroundTemplate = ({backgroundColor}) => { - return ( -
- // access the color picker + display the hex value as a label - - // pass in a primitive, hex value, etc. - -
- ) -} -``` - -#### Color Playground - -If you're just working with color, Color Playground is a quick start template for manipulating `ColorBlock`. Repeat `` as many times as you need to test combinations. diff --git a/docs/src/stories/principles/Accessibility.mdx b/docs/src/stories/principles/Accessibility.mdx new file mode 100644 index 0000000000..6c3811abcf --- /dev/null +++ b/docs/src/stories/principles/Accessibility.mdx @@ -0,0 +1,186 @@ +# Accessibility + +Accessibility is everyone’s responsibility, and the purpose of this document is to provide general accessibility guidelines to developers and designers. + +## Overview + +Our products should be accessible to all. At minimum, features should comply to the requirements listed in [508 Reference Guide - 1194.22](https://www.access-board.gov/guidelines-and-standards/communications-and-it/about-the-section-508-standards/guide-to-the-section-508-standards/web-based-intranet-and-internet-information-and-applications-1194-22) from the US Access Board, and conform to [Web Content Accessibility Guidelines 2.0](https://www.w3.org/TR/WCAG20/#conformance) at Level AA. + +Making our products accessible benefits everyone, not just people with disabilities. Below are some examples of use cases in which accessibility is important: + +- **Visual**: blindness, low vision, color blindness, using a screen reader or related assistive tech for lifestyle reasons (e.g. long car commute), machine readability and screen scraping technologies + +- **Hearing**: deafness, hearing impairment, speech impairment, using closed captioning or other assistive features for lifestyle reasons (e.g. coworking in a loud coffee shop) + +- **Cognitive**: including short-term memory issues, dyslexia, learning disabilities, trying to work or consume content while distracted or multitasking, etc. + +- **Mobility**: mobility impairments, repetitive stress injuries, power users who love keyboard shortcuts, busy parents holding a sleeping child while trying to operate a computer with one hand, etc. + +## General guidelines + +### Semantic markup + +Always use semantic HTML elements, like `button`, `ul`, `nav`. Most modern browsers implement the accessibility features outlined in the specs for these elements; without them, elements will need additional [ARIA attributes and roles](https://www.w3.org/WAI/PF/aria) to be recognized by assistive technologies. + +Elements like `h1`-`h6`, `nav`, `footer`, `header` have [meaningful roles](https://www.w3.org/WAI/PF/aria/roles) assigned, so use them carefully. This can help assistive technologies read the page better and help users find information quicker. + +Only use a `div` or a `span` to markup up content when there isn't another HTML element that would semantically be more appropriate, or when an element is needed exclusively for applying CSS styles or JS behaviors. + +```html + + +``` + +```html + +Send +``` + +> More on semantic markup: +> +> - [Semantic Structure – WebAIM](http://webaim.org/techniques/semanticstructure/) + +### Keyboard accessibility + +Make sure elements can be reached via tabbing, and actions can be triggered with a keyboard. Using semantic markup is especially important in this case as it ensures that actionable elements are tabbable and triggerable without a mouse. Note that elements positioned off-screen are still tabbable, but those hidden with `display: none` or `visibility: hidden` are effectively removed from content since they are neither read by screen readers nor reachable by keyboard. + +Tab order is determined by the order of elements in the DOM, and not by their visual positioning on the page after CSS is applied. CSS properties `float` and `order` for flex items are two common sources for disconnection between visual and DOM order. + +The `tabindex` attribute should only be used when absolutely necessary. + +- `tabindex=0/-1` makes an element focusable, while `tabindex=0` also includes the element in the normal tab order. In both cases, keyboard triggers of the element still require scripting, so where possible, use [interactive content](http://w3c.github.io/html/dom.html#kinds-of-content-interactive-content) instead. + +- `tabindex=1+` takes an element to the very front of the default tab order. When it's applied, the element's visual positioning is no longer indicative of its tab order, and the only way to find out where an element is would be by tabbing through the page. Therefore, unless a page is carefully designed around elements with positive tabindex, it is very error-prone, and thus currently prohibited in github.com. + +Finally, bear in mind that some assistive technologies have keyboard combinations of their own that will override the combination on the web page, so don't rely on keyboard shortcuts as the only alternative to mouse actions. + +```html + + + + +``` + +```html + + + + +``` + +> More on keyboard accessibility: +> +> - [Focus Order – Understanding WCAG 2.0](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-focus-order.html) +> - [Time to revisit accesskey? by Léonie Watson](http://tink.uk/time-to-revisit-accesskey/) +> - [Flexbox & the keyboard navigation disconnect by Léonie Watson](http://tink.uk/flexbox-the-keyboard-navigation-disconnect/) + +### Visual accessibility + +Be mindful when using small font size, thin font weight, low contrast colors in designs as it can severely affect usability. + +Instead of relying solely on color to communicate information, always combine color with another factor, like shape or position change. This is important because some colors can be hard to tell apart due to color blindness or weak eyesight. + +> More on visual accessibility: +> +> - [Use of Color – Understanding WCAG 2.0](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-without-color.html) +> - [Contrast – Understanding WCAG 2.0](http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html) + +### Text and labels + +Make sure text-based alternative is always available when using icons, images, and graphs, and that the text by itself presents meaningful information. + +```html + +

Find out more about GitHub Enterprise pricing.

+``` + +```html + +

To find out more about GitHub Enterprise pricing, click here.

+``` + +Use `aria-label` when there is no text. + +```html +<%= octicon("question", :"aria-label" => "Help") %> +``` + +### Link responsibly + +Navigating from a list of all the links on a given web page is very common for assistive technology users. We should make sure that the link text itself is meaningful and unique, and there should be as few duplicated references as possible. + +> More on link responsibly: +> +> - [Link Purpose – Understanding WCAG 2.0](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-refs.html) + +### Dynamic content + +When using JavaScript to change the content on the page, always make sure that screen reader users are informed about the change. This can be done with `aria-live`, or focus management. + +> More on dynamic content: +> +> - [ARIA Live Regions – MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) + +### Focus management + +Focus management is useful for informing users about updated content, and for making sure users land on the next useful section after performing an action. This means using scripts to change user’s currently focused element, and when focus changes, screen readers will read out change. + +### Accessible forms + +It is common for assistive technology users to jump straight to a form when using a website, so make sure most relevant information is in the form and is labelled properly. Labels and inputs should be associated with the `label[for]` and `input[id]`, and help texts should either be part of the label or be associated with `aria-describedby`. + +```html + +
+ +
Please enter an email ending with @github.com.
+``` + +```html + +
+ +
Please enter an email ending with @github.com.
+``` + +## Development tools + +### Linting + +We currently run basic linting [against positive `tabindex`](https://github.com/github/github/blob/8546895623677abc70f61951642f32c16de231a1/test/fast/linting/accessible_tabindex_test.rb) and [anchor links with `href="#"`](https://github.com/github/github/blob/8546895623677abc70f61951642f32c16de231a1/test/rubocop/cop/rails/link_href.rb). + +We do client side scanning of inaccessible elements in development environment. The inaccessible elements will be styled with red borders with an onclick alert and console warnings. + +### External tools + +- Google Chrome provides an [Accessibility Developer Tools extension](https://chrome.google.com/webstore/detail/accessibility-developer-t/fpkknkljclfencbdbgkenhalefipecmb). Once installed, go to Audits tab in developer tools, tick Accessibility. It scans the page for violations and suggests solutions. + +- If you're working on a design that uses color to communicate something, grab the [Chromatic Vision Simulator app](https://itunes.apple.com/tw/app/chromatic-vision-simulator/id389310222?mt=8), this will let you use your iPhone camera to see what a colorblind person would see. + +- Check out [the Web Accessibility showcase on GitHub](https://github.com/showcases/web-accessibility). GitHubbers are free to add more projects to the showcase. + +## Manual testing + +### Screen reader + +To use VoiceOver, the built-in screen reader for Mac, just hit + F5. This will start voice narration and display most of the spoken information in a text box. + +Use alt + control + left/right to navigate a web page. alt + control + space to click on an element. For more help with VoiceOver, check out the built-in tutorial in `System Preferences > Accessibility > VoiceOver > Open VoiceOver Training`. + +Keep in mind that behaviors in different screen readers can differ when navigating the same web page; just like designing for different browsers, when it comes to accessibility, it is not just the implementation of the browsers that can be different, but also the ones of assistive softwares. + +## Internal resources + +1. You can mention these teams when looking for help: + +- [@github/accessibility](https://github.com/orgs/github/teams/accessibility): GitHubbers interested in accessibility related topics and work on website accessibility issues. +- [@github/colorblind](https://github.com/orgs/github/teams/colorblind): GitHubbers who are interested in accessibility for colorblindness. + +2. Go to #accessibility Slack channel to ask questions or discuss accessibility issues. +3. Check [github/accessibility repository](https://github.com/github/accessibility) for information on events or learning resources. + +## User support + +Accessibility is a priority for us, if you ever encounter accessibility related issues when using github.com, please don’t hesitate to reach out to us via [the contact page](https://github.com/contact) or email us at [support@github.com](mailto:support@github.com), we will try our best to assist. + +For information about the accessibility compliance of GitHub products, please refer to our [VPAT report, outlining §508 accessibility information for GitHub.com, GitHub Enterprise, and GitHub Desktop](https://government.github.com/accessibility/). diff --git a/docs/src/stories/principles/HTML.mdx b/docs/src/stories/principles/HTML.mdx new file mode 100644 index 0000000000..84bafccd52 --- /dev/null +++ b/docs/src/stories/principles/HTML.mdx @@ -0,0 +1,78 @@ +# HTML + +## General formatting + +- Use soft-tabs with a two space indent. Spaces are the only way to guarantee code renders the same in any person's environment. +- Paragraphs of text should always be placed in a `

` tag. Never use multiple `
` tags. +- Items in list form should always be in `

    `, `
      `, or `
      `. Never use a set of `
      ` or `

      `. +- Every form input that has text attached should utilize a `


      `, ``, and ``. +- Don't set `tabindex` manually—rely on the browser to set the order. + +```html inert=true +

      This is my paragraph of special text.

      +``` + +## Boolean attributes + +Many attributes don't require a value to be set, like `checked`, so don't set them. + +```html inert=true + + + +``` + +For more information, [read the WhatWG section](http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#boolean-attributes). + +## Lean markup + +Whenever possible, avoid superfluous parent elements when writing HTML. Many times this requires iteration and refactoring, but produces less HTML. For example: + +```html inert=true + + + + + + + +``` + +## Forms + +- Lean towards radio or checkbox lists instead of select menus. +- Wrap radio and checkbox inputs and their text in `