diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc261a612c..21780c48c4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [develop] + branches: [develop, stacks-next] pull_request: - branches: [develop] + branches: [develop, stacks-next] jobs: build-and-test: @@ -30,6 +30,9 @@ jobs: - name: ▶️ Linting run: npm run lint + - name: ▶️ Less Tests + run: npm run test:less + - name: ▶️ Unit Tests run: npm run test:unit -- --config web-test-runner.config.ci.mjs diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md new file mode 100755 index 0000000000..cd3cae270c --- /dev/null +++ b/MIGRATION_GUIDE.md @@ -0,0 +1,198 @@ +# Migrating from Stacks v1 to v2 + +With the release of Stacks v2, we've made some breaking changes to the library. The purpose of this guide is to help you prepare your code be compatible with the changes in Stacks v2. + +## Table of contents + +- [Upgrading dependencies](#upgrading-dependencies) +- [Using Stacks v2 colors](#using-stacks-v2-colors) + - [Color stop mappings](#color-stop-mappings) + - [Orange, blue, green, red, yellow, theme-primary, theme-secondary](#orange-blue-green-red-yellow-theme-primary-theme-secondary) + - [Black](#black) + - [Gold, sliver, bronze](#gold-sliver-bronze) + - [Regular expression patterns](#regular-expression-patterns) + - [Deprecation of powder color set](#deprecation-of-powder-color-set) + - [Referencing theme colors without stop suffix](#referencing-theme-colors-without-the-stop-suffix) +- [Deprecation of Less color variables](#deprecation-of-less-color-variables) + - [Replacing Less color variables](#replacing-less-color-variables) + - [Referencing Less color variables](#referencing-less-color-variables) +- [Using legacy colors](#using-legacy-colors) + - [Using the `-legacy` suffix](#using-the--legacy-suffix) + - [Examples of legacy color references](#examples-of-legacy-color-references) + - [Helpful regular expressions](#helpful-regular-expressions) + - [Add `-legacy` suffix to colors](#add--legacy-suffix-to-colors) + - [Add `-legacy` to aliased values](#add--legacy-to-aliased-values) +- [Custom theme generation](#custom-theme-generation) + - [Replacing `.generate-calculated-themed-variables()`](#replacing-generate-calculated-themed-variables) +- [Deprecation of `.s-btn__primary`](#deprecation-of-s-btn__primary) + +## Upgrading dependencies + +While updating to Stacks v2, you must also update other Stacks dependencies you may have included in your project. Below is a table of Stacks dependencies and the corresponding minimum versions compatible with Stacks v2. + +Dependency | Minimum version +:-:|:-: +[stacks](https://github.com/StackExchange/Stacks) | [2.0.0](https://www.npmjs.com/package/@stackoverflow/stacks/v/2.0.0) +[stacks-editor](https://github.com/StackExchange/Stacks-Editor) | [0.9.0](https://www.npmjs.com/package/@stackoverflow/stacks-editor/v/0.9.0) +[stacks-icons](https://github.com/StackExchange/Stacks-Icons) | [6.0.0](https://www.npmjs.com/package/@stackoverflow/stacks-icons/v/6.0.0) + +## Using Stacks v2 colors + +In Stacks v2, all components and atomic classes have been updated to use new color sets optimized for accessibility. In the process, the previous colors have been deprecated and the number of color stops has been reduced. This section will help you migrate to use the new colors. + +### Color stop mappings + +Stacks v2 reduces and unifies the number of color stops for each set of colors. Below, you'll find a series of tables that map the old color stops to the new color stops. Update your color references by mapping them to the new stop values. + +> **Note** +> The `powder` color set has been deprecated and is not included in the updated colors. See the [deprecation of powder color set](#deprecation-of-powder-color-set) section for more information. + +#### Orange, blue, green, red, yellow, theme-primary, theme-secondary + +Stacks v1 | Stacks v2 +:-:|:-: +025*† | 100 +050, 075* | 200 +100, 150*, 200 | 300 +300, 350*, 400, 500 | 400 +600, 700 | 500 +800, 900 | 600 + +- *only applies to theme colors +- †only applies to green and red + +#### Black + +Stacks v1 | Stacks v2 +:-:|:-: +N/A | 050 +025 | 100 +050 | 150 +075 | 200 +100 | 225 +150 | 250 +200 | 300 +300, 350 | 350 +400, 500 | 400 +600, 700 | 500 +750, 800, 900 | 600 + +#### Gold, sliver, bronze + +Stacks v1 | Stacks v2 +:-:|:-: +[color]-lighter | 100 +N/A | 200 +[color] | 300 +[color]-darker | 400 + +#### Regular expression patterns + +Below is just one example of a regular expression that can help you find and replace color references. Swap the color names and stop suffixes to update different remappings. + +###### Find +```regexp +(theme-primary|theme-secondary|orange|blue|green|red|yellow)-(100|150|200) +``` + +###### Replace +```regexp +$1-300 +``` + +### Deprecation of `powder` color set + +Stacks v2 no longer includes the `powder` color set. We recommend you replace all references to `powder` with `blue`. If you need to continuing referencing `powder`, you can use the `-legacy` suffix until the library permanently removes legacy colors. See the [using legacy colors](#using-legacy-colors) section for more information. + +### Referencing theme colors without the stop suffix + +We've removed the `-color` suffix from the default theme variable custom properties. Previously, you could reference the 400 stop of theme colors with `theme-(primary|secondary)-color`. Now, you should reference the 400 stop of theme colors with `theme-(primary|secondary)`. Below is a table showing the old and new custom property names, though this pattern also applies to color, background, and border utility classes. + +Variable | Stacks v1 | Stacks v2 +:-:|:-:|:-: +**Primary** | `--theme-primary-color` | `--theme-primary` +**Secondary** | `--theme-secondary-color` | `--theme-secondary` + +## Deprecation of Less color variables + +Stacks v2 deprecates the usage of Less variables outside of Stacks. Although there's no way to make these variables truly private, we now discourage referencing them directly unless otherwise stated in our official documentation and advise that changes to psuedo-private variables may break your code if you reference them. + +### Replacing Less color variables + +Stacks v2 includes new CSS custom properties to replace a handful of commonly referenced Less variables. Update your Less variable references to the new CSS custom properties where possible. + +Stacks v1 | Stacks v2 +:-:|:-: +`@black` | `var(--_black-static)` +`@white` | `var(--_white-static)` + +### Referencing Less color variables + +In rare circumstances, you may need to reference a color value directly in order to operate on it and generate a new color or extract some value. In these cases, you *can* reference colors within a given color set. We advise against this and don't guarantee that these variables will remain stable. Nevertheless, here's how you would reference a Less color variable in Stacks v2. + +Stacks v1 | Stacks v2 +:-:|:-: +`@black-350` | `.set-black()[350]` + +## Using legacy colors + +Legacy colors are deprecated and will be removed January 2024. We **strongly** recommend you migrate to the new colors as soon as possible. With that said, you may have a need to reference legacy colors in the short term. This section gives an overview of how to reference legacy colors. + +### Using the `-legacy` suffix + +Stacks v2 replaces v1 colors, but you can still reference the v1 colors by adding the `-legacy` label to your color references. The `-legacy` suffix will generally come *after* the color name and *before* a color stop suffix (if it exists). This applies to atomic color classes (such as `.bc-*`, `.bg-*`, and `.fc-*`), CSS custom properties, and Less variables. See the [legacy color documentation](https://stackoverflow.design/product/v1/base/colors/) for more information. + +### Examples of legacy color references + +Stacks v1 | Stacks v2 +:-:|:-: +`.bc-red-800` | `.bc-red-legacy-800` +`--theme-secondary-400` | `--theme-secondary-legacy-400` +`--theme-base-primary-color-h` | `--theme-base-primary-color-legacy-h` +`.fc-light` | `.fc-light-legacy` +`.fc-white__forced` | `.fc-white-legacy__forced` +`@black` | `@black-legacy` + +### Helpful regular expressions + +Below you'll find a set of regular expressions to help you find and replace existing color references with corresponding legacy reference. + +> **Note** +> Even with these regular expressions, you'll may still need to find and replace some color references manually. For example, this regex will not alter references to `black` that don't contain a numeric stop suffix. + +#### Add `-legacy` suffix to colors + +##### Find +```regexp +(theme-primary|theme-secondary|black|orange|blue|green|red|yellow|powder|fog)-(025|050|075|100|150|200|300|350|400|500|600|700|750|800|900) +``` + +##### Replace +```regexp +// Replace +$1-legacy-$2 +``` + +#### Add `-legacy` to aliased values + +##### Find +```regexp +(bc|fc|bg)-(lightest|lighter|light|medium|darker|dark) +``` + +##### Replace +```regexp +$1-$2-legacy +``` + +## Custom theme generation + +Stacks v2 has deprecated the Less function `.generate-calculated-themed-variables()` in favor of the newly added `.create-custom-theme-hsl-variables()` function. This new function works differently behind the scenes, but it accepts the same arguments and generates the same CSS custom properties as its deprecated equivelent. See the [theming documentation](https://stackoverflow.design/product/guidelines/theming/). + +### Replacing `.generate-calculated-themed-variables()` + +To update to the new custom theme variable generation function, simply search for `.generate-calculated-themed-variables` in your codebase and replace it with `.create-custom-theme-hsl-variables`. + +## Deprecation of `.s-btn__primary` + +Stacks v2 deprecates the `.s-btn__primary` variant. To retain a similar style, we recommend replacing all instances of `.s-btn__primary` with `.s-btn__filled`. See the [button documentation](https://stackoverflow.design/product/components/buttons/) for more information. diff --git a/README.md b/README.md index a8cdca869a..b6e029f023 100755 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Stacks documentation can be found at https://stackoverflow.design/ ## Table of contents - [Using Stacks](#using-stacks) +- [Migrating from v1 to v2](#migrating-from-v1-to-v2) - [Building Stacks](#building-stacks) - [Format Stacks](#format-stacks) - [Linting Stacks](#linting-stacks) @@ -33,6 +34,10 @@ Stacks documentation can be found at https://stackoverflow.design/ ## Using Stacks Using Stacks is outlined in our [usage guidelines](https://stackoverflow.design/product/guidelines/using-stacks). +## Migrating from v1 to v2 + +To migrate from Stacks v1 to v2, see our [migration guide](/MIGRATION_GUIDE.md). + ## Building Stacks To contribute to Stacks documentation or its CSS library, you’ll need to build Stacks locally. View our [building guidelines](https://stackoverflow.design/product/guidelines/building). @@ -109,6 +114,21 @@ npm run test:visual:update Failing tests (including diffs) can be found under `screenshots/[browser]/failed/` folders. +### Less Tests + +This is an experimental suite to test the generation of CSS from Less files. +Less tests end with this suffix `*.less.test.ts`. + +Execute the less tests suite by running: +```sh +npm run test:less +``` + +Update the css snapshots via: +```sh +npm run test:less:update +``` + ## Releasing a new version of Stacks Stacks uses [Semantic Versioning](https://semver.org/), is distributed via [npm](https://www.npmjs.com/package/@stackoverflow/stacks), and publishes [release notes on Github](https://github.com/StackExchange/Stacks/releases). Follow the steps below to release a new version of Stacks. diff --git a/adrs/0001-pseudo-private-custom-properties.md b/adrs/0001-pseudo-private-custom-properties.md index 797516af00..0f8a352168 100644 --- a/adrs/0001-pseudo-private-custom-properties.md +++ b/adrs/0001-pseudo-private-custom-properties.md @@ -89,7 +89,7 @@ Defining a structure for component styles using pseudo-private custom properties --_cn-bg: var(--yellow-100); &.s-component-name__filled { - --_cn-bg-filled: var(--yellow-800); + --_cn-bg-filled: var(--yellow-600); } } @@ -100,7 +100,7 @@ Defining a structure for component styles using pseudo-private custom properties // INTERACTION &:hover { - --_cn-bg: var(--_black-050); + --_cn-bg: var(--black-150); } // STYLES MODIFIED BY COMPONENT-SPECIFIC CUSTOM PROPERTIES diff --git a/docs/_data/borders.json b/docs/_data/borders.json index 0027417ebf..0102911096 100755 --- a/docs/_data/borders.json +++ b/docs/_data/borders.json @@ -1,189 +1,189 @@ { "border": [ { - "class": ".ba", - "define": "Apply a border to all sides", + "class": "ba", + "define": "all sides", "output": "border: solid 1px #000", "responsive": true }, { - "class": ".bt", - "define": "Apply a border to the top side", + "class": "bt", + "define": "top", "output": "border-top: solid 1px #000", "responsive": true }, { - "class": ".bb", - "define": "Apply a border to the bottom side", + "class": "bb", + "define": "bottom", "output": "border-bottom: solid 1px #000", "responsive": true }, { - "class": ".bl", - "define": "Apply a border to the left side", + "class": "bl", + "define": "left", "output": "border-left: solid 1px #000", "responsive": true }, { - "class": ".br", - "define": "Apply a border to the right side", + "class": "br", + "define": "right", "output": "border-right: solid 1px #000", "responsive": true }, { - "class": ".by", - "define": "Apply a border to the top and bottom sides", + "class": "by", + "define": "top and bottom", "output": "border-top: solid 1px #000; border-bottom: solid 1px #000;" }, { - "class": ".bx", - "define": "Apply a border to the left and right sides", + "class": "bx", + "define": "left and right", "output": "border-left: solid 1px #000; border-right: solid 1px #000;" } ], - "border-width": [ + "width": [ { - "class": ".baw0", - "define": "Applies a border width of zero to all sides", + "class": "baw0", + "define": "zero, all sides", "output": "border-width: 0" }, { - "class": ".btw0", - "define": "Applies a border width of zero to the top side", + "class": "btw0", + "define": "zero, top", "output": "border-top-width: 0", "responsive": true }, { - "class": ".bbw0", - "define": "Applies a border width of zero to the bottom side", + "class": "bbw0", + "define": "zero, bottom", "output": "border-bottom-width: 0", "responsive": true }, { - "class": ".blw0", - "define": "Applies a border width of zero to the left side", + "class": "blw0", + "define": "zero, left", "output": "border-left-width: 0", "responsive": true }, { - "class": ".brw0", - "define": "Applies a border width of zero to the right side", + "class": "brw0", + "define": "zero, right", "output": "border-right-width: 0", "responsive": true }, { - "class": ".byw0", - "define": "Applies a border width of zero to the top and bottom sides", + "class": "byw0", + "define": "zero, top and bottom", "output": "border-top-width: 0; border-bottom-width: 0;" }, { - "class": ".bxw0", - "define": "Applies a border width of zero to the left and right sides", + "class": "bxw0", + "define": "zero, left and right", "output": "border-left-width: 0; border-right-width: 0;" }, { - "class": ".baw1", - "define": "Applies a border width of 1px to all sides", + "class": "baw1", + "define": "1px, all", "output": "border-width: 1px" }, { - "class": ".btw1", - "define": "Applies a border width of 1px to the top side", + "class": "btw1", + "define": "1px, top", "output": "border-top-width: 1px" }, { - "class": ".bbw1", - "define": "Applies a border width of 1px to the bottom side", + "class": "bbw1", + "define": "1px, bottom", "output": "border-bottom-width: 1px" }, { - "class": ".blw1", - "define": "Applies a border width of 1px to the left side", + "class": "blw1", + "define": "1px, left", "output": "border-left-width: 1px" }, { - "class": ".brw1", - "define": "Applies a border width of 1px to the right side", + "class": "brw1", + "define": "1px, right", "output": "border-right-width: 1px" }, { - "class": ".byw1", - "define": "Applies a border width of 1px to the top and bottom sides", + "class": "byw1", + "define": "1px, top and bottom", "output": "border-top-width: 1px; border-bottom-width: 1px;" }, { - "class": ".bxw1", - "define": "Applies a border width of 1px to the left and right sides", + "class": "bxw1", + "define": "1px, left and right", "output": "border-left-width: 1px; border-right-width: 1px;" }, { - "class": ".baw2", - "define": "Applies a border width of 2px to all sides", + "class": "baw2", + "define": "2px, all", "output": "border-width: 2px" }, { - "class": ".btw2", - "define": "Applies a border width of 2px to the top side", + "class": "btw2", + "define": "2px, top", "output": "border-top-width: 2px" }, { - "class": ".bbw2", - "define": "Applies a border width of 2px to the bottom side", + "class": "bbw2", + "define": "2px, bottom", "output": "border-bottom-width: 2px" }, { - "class": ".blw2", - "define": "Applies a border width of 2px to the left side", + "class": "blw2", + "define": "2px, left", "output": "border-left-width: 2px" }, { - "class": ".brw2", - "define": "Applies a border width of 2px to the right side", + "class": "brw2", + "define": "2px, right", "output": "border-right-width: 2px" }, { - "class": ".byw2", - "define": "Applies a border width of 2px to the top and bottom sides", + "class": "byw2", + "define": "2px, top and bottom", "output": "border-top-width: 2px; border-bottom-width: 2px;" }, { - "class": ".bxw2", - "define": "Applies a border width of 2px to the left and right sides", + "class": "bxw2", + "define": "2px, left and right", "output": "border-left-width: 2px; border-right-width: 2px;" }, { - "class": ".baw3", - "define": "Applies a border width of 4px to all sides", + "class": "baw3", + "define": "4px, all", "output": "border-width: 4px" }, { - "class": ".btw3", - "define": "Applies a border width of 4px to the top side", + "class": "btw3", + "define": "4px, top", "output": "border-top-width: 4px" }, { - "class": ".bbw3", - "define": "Applies a border width of 4px to the bottom side", + "class": "bbw3", + "define": "4px, bottom", "output": "border-bottom-width: 4px" }, { - "class": ".blw3", - "define": "Applies a border width of 4px to the left side", + "class": "blw3", + "define": "4px, left", "output": "border-left-width: 4px" }, { - "class": ".brw3", - "define": "Applies a border width of 4px to the right side", + "class": "brw3", + "define": "4px, right", "output": "border-right-width: 4px" }, { - "class": ".byw3", - "define": "Applies a border width of 4px to the top and bottom sides", + "class": "byw3", + "define": "4px, top and bottom", "output": "border-top-width: 4px; border-bottom-width: 4px;" }, { - "class": ".bxw3", - "define": "Applies a border width of 4px to the left and right sides", + "class": "bxw3", + "define": "4px, left and right", "output": "border-left-width: 4px; border-right-width: 4px;" } ], @@ -239,65 +239,6 @@ "output": "border-left-style: dashed" } ], - "border-color": [ - { - "term": "bc-transparent", - "define": "Transparent border color", - "darkmode": true - }, - { - "term": "bc-white", - "define": "White border color" - }, - { - "term": "bc-white-[x]", - "define": "Alpha stops for border color" - }, - { - "term": "bc-black-[x]", - "define": "Black color stops for border colors" - }, - { - "term": "bc-orange-[x]", - "define": "Orange color stops for border colors" - }, - { - "term": "bc-blue-[x]", - "define": "Blue color stops for border colors" - }, - { - "term": "bc-green-[x]", - "define": "Green color stops for border colors" - }, - { - "term": "bc-powder-[x]", - "define": "Powder color stops for border colors" - }, - { - "term": "bc-red-[x]", - "define": "Red color stops for border colors" - }, - { - "term": "bc-yellow-[x]", - "define": "Yellow color stops for border colors" - }, - { - "term": "bc-danger", - "define": "Danger border color alias" - }, - { - "term": "bc-error", - "define": "Error border color alias" - }, - { - "term": "bc-success", - "define": "Success border color alias" - }, - { - "term": "bc-warning", - "define": "Warning border color alias" - } - ], "border-radius-definitions": [ { "term": "bar", diff --git a/docs/_data/buttons.json b/docs/_data/buttons.json index 5284c0e817..cfc74740a5 100755 --- a/docs/_data/buttons.json +++ b/docs/_data/buttons.json @@ -1,7 +1,7 @@ { - "secondary": [ + "base": [ { - "title": "Secondary", + "title": "Base", "classes": [ { "title": "Clear" @@ -71,10 +71,6 @@ "title": "Loaders", "class": "is-loading", "classes": [ - { - "title": "Primary", - "class": "s-btn__primary" - }, { "title": "Secondary, Clear" }, @@ -117,10 +113,6 @@ "title": "Dropdown", "class": "s-btn__dropdown", "classes": [ - { - "title": "Primary", - "class": "s-btn__primary" - }, { "title": "Secondary, Clear" }, @@ -163,10 +155,6 @@ "title": "Badge", "class": "s-btn--badge", "classes": [ - { - "title": "Primary", - "class": "s-btn__primary" - }, { "title": "Secondary, Clear" }, diff --git a/docs/_data/colors.json b/docs/_data/colors.json index e5e64ec19d..e8e47fbe5e 100755 --- a/docs/_data/colors.json +++ b/docs/_data/colors.json @@ -1,592 +1,422 @@ [ { - "name": "red", - "primary": 400, - "white": true, - "include": true, - "stops": [ + "name": "v2", + "sets": [ { - "stop": 900, - "hex": "7a1819", - "white": true + "name": "theme primary", + "stops": ["", 100, 200, 300, 400, 500, 600], + "invert": ["", 400, 500, 600], + "type": "theme" }, { - "stop": 800, - "hex": 942121, - "white": true + "name": "theme secondary", + "stops": ["", 100, 200, 300, 400, 500, 600], + "invert":["", 400, 500, 600], + "type": "theme" }, { - "stop": 700, - "hex": "ac2726", - "white": true + "name": "orange", + "stops": [100, 200, 300, 400, 500, 600], + "invert": [400, 500, 600], + "type": "color" }, { - "stop": 600, - "hex": "c02d2e", - "white": true + "name": "blue", + "stops": [100, 200, 300, 400, 500, 600], + "invert": [400, 500, 600], + "type": "color" }, { - "stop": 500, - "hex": "d1383d", - "white": true + "name": "green", + "stops": [100, 200, 300, 400, 500, 600], + "invert": [400, 500, 600], + "type": "color" }, { - "stop": 400, - "hex": "de535e", - "white": true + "name": "red", + "stops": [100, 200, 300, 400, 500, 600], + "invert": [400, 500, 600], + "type": "color" }, { - "stop": 300, - "hex": "e87c87" + "name": "yellow", + "stops": [100, 200, 300, 400, 500, 600], + "invert": [400, 500, 600], + "invertAlt": "yellow-600", + "type": "color" }, { - "stop": 200, - "hex": "f4b4bb" + "name": "purple", + "stops": [100, 200, 300, 400, 500, 600], + "invert": [400, 500, 600], + "invertAlt": "purple-600", + "type": "color" }, { - "stop": 100, - "hex": "f9d3d7" + "name": "gold", + "stops": [100, 200, 300, 400], + "invert": [400], + "invertAlt": "gold-400", + "type": "award" }, { - "stop": "050", - "hex": "fdf3f4" + "name": "silver", + "stops": [100, 200, 300, 400], + "invert": [400], + "invertAlt": "silver-400", + "type": "award" }, { - "stop": "025" - } - ] - }, - { - "name": "orange", - "primary": 400, - "white": true, - "include": true, - "stops": [ - { - "stop": 900, - "hex": 874600, - "white": true - }, - { - "stop": 800, - "hex": "a35200", - "white": true + "name": "bronze", + "stops": [100, 200, 300, 400], + "invert": [400], + "invertAlt": "bronze-400", + "type": "award" }, { - "stop": 700, - "hex": "bd5c00", - "white": true + "name": "black", + "stops": ["050", 100, 150, 200, 225, 250, 300, 350, 400, 500, 600, ""], + "invert": [400, 500, 600, ""], + "invertAlt": "black-600", + "type": "monochrome" }, { - "stop": 600, - "hex": "da670b", - "white": true - }, - { - "stop": 500, - "hex": "f2720c", - "white": true - }, - { - "stop": 400, - "hex": "f48024", - "white": true - }, - { - "stop": 300, - "hex": "f7aa6d" - }, - { - "stop": 200, - "hex": "fcd0ad" - }, - { - "stop": 100, - "hex": "fee3cf" - }, - { - "stop": "050", - "hex": "fff7f2" + "name": "white", + "stops": [""], + "invertAlt": "black-600", + "type": "monochrome" } - ] - }, - { - "name": "yellow", - "primary": 500, - "white": true, - "include": true, - "stops": [ - { - "stop": 900, - "hex": "826a0b", - "white": true - }, + ], + "roles": [ { - "stop": 800, - "hex": "9f8010", - "white": true + "name": "neutral", + "description": "Use for text and secondary UI elements, such as buttons", + "bg": "black-400" }, { - "stop": 700, - "hex": "b89516", - "white": true + "name": "primary", + "description": "Use for primary actions", + "bg": "theme-secondary" }, { - "stop": 600, - "hex": "cea51b", - "white": true + "name": "accent", + "description": "Use for UI that either relates to the brand or doesn’t have a specific meaning tied to it.", + "bg": "theme-primary" }, { - "stop": 500, - "hex": "ddb624", - "white": true + "name": "information", + "description": "Use for UI to communicate information that you’d like the user to be aware of", + "bg": "blue-400" }, { - "stop": 400, - "hex": "e9c63f", - "white": true + "name": "success", + "description": "Use for UI to communicate a successful action has taken place", + "bg": "success" }, { - "stop": 300, - "hex": "e6d178" + "name": "warning", + "description": "Use for UI that communicates a user should proceed with caution", + "bg": "warning" }, { - "stop": 200, - "hex": "f1e5bc" + "name": "danger", + "description": "Use for UI that communicates the user has encountered danger or an error", + "bg": "danger" }, { - "stop": 100, - "hex": "fbf2d4" - }, - { - "stop": "050", - "hex": "fdf7e3" + "name": "discovery", + "description": "Use for UI that depicts something new, such as onboarding or a new feature ", + "bg": "purple-400" } - ] - }, - { - "name": "green", - "primary": 500, - "white": true, - "include": true, - "stops": [ - { - "stop": 900, - "hex": "1e472c", - "white": true - }, - { - "stop": 800, - "hex": "29603b", - "white": true - }, - { - "stop": 700, - "hex": "2f6f44", - "white": true - }, - { - "stop": 600, - "hex": "3d8f58", - "white": true - }, - { - "stop": 500, - "hex": "48a868", - "white": true - }, - { - "stop": 400, - "hex": "5eba7d", - "white": true - }, - { - "stop": 300, - "hex": "82ca9a" - }, + ], + "layers": [ { - "stop": 200, - "hex": "a6d9b7" + "name": "Body background", + "color": "white", + "teamsLight": "black-100", + "soLight": "black-050" }, { - "stop": 100, - "hex": "cae8d4" + "name": "Content", + "color": "black-050" }, { - "stop": "050", - "hex": "dcf0e2" + "name": "Component", + "color": "black-100" }, { - "stop": "025", - "hex": "eef8f1" + "name": "Component Alt", + "color": "black-150" } - ] - }, - { - "name": "blue", - "primary": 600, - "white": true, - "include": true, - "stops": [ - { - "stop": 900, - "hex": "004487", - "white": true - }, - { - "stop": 800, - "hex": "0054a3", - "white": true - }, - { - "stop": 700, - "hex": "0064bd", - "white": true - }, - { - "stop": 600, - "hex": "0077cc", - "white": true - }, - { - "stop": 500, - "hex": "0095ff", - "white": true - }, - { - "stop": 400, - "hex": "379fef", - "white": true - }, - { - "stop": 300, - "hex": "6cbbf7" - }, - { - "stop": 200, - "hex": "addafc" - }, - { - "stop": 100, - "hex": "cfeafe" - }, - { - "stop": "050", - "hex": "f2f9ff" + ], + "emphasis": [ + { + "name": "Bold", + "textClasses": "fc-black", + "colors": [ + { + "name": "black", + "classes": "bg-black-500 fc-white" + }, { + "name": "orange", + "classes": "bg-orange-400 fc-white" + }, { + "name": "blue", + "classes": "bg-blue-400 fc-white" + }, { + "name": "green", + "classes": "bg-green-400 fc-white" + }, { + "name": "red", + "classes": "bg-red-400 fc-white" + }, { + "name": "yellow", + "classes": "bg-yellow-400 fc-black" + } + ] + }, { + "name": "Default", + "textClasses": "fc-black-500", + "colors": [ + { + "name": "black", + "classes": "bg-black-200 fc-black-600" + }, { + "name": "orange", + "classes": "bg-orange-200 fc-orange-600" + }, { + "name": "blue", + "classes": "bg-blue-200 fc-blue-600" + }, { + "name": "green", + "classes": "bg-green-200 fc-green-600" + }, { + "name": "red", + "classes": "bg-red-200 fc-red-600" + }, { + "name": "yellow", + "classes": "bg-yellow-200 fc-yellow-600" + } + ] + }, { + "name": "Subtle", + "textClasses": "fc-black-400", + "colors": [ + { + "name": "black", + "classes": "bg-black-150 fc-black-500" + }, { + "name": "orange", + "classes": "bg-orange-100 fc-orange-500" + }, { + "name": "blue", + "classes": "bg-blue-100 fc-blue-500" + }, { + "name": "green", + "classes": "bg-green-100 fc-green-500" + }, { + "name": "red", + "classes": "bg-red-100 fc-red-500" + }, { + "name": "yellow", + "classes": "bg-yellow-100 fc-yellow-500" + } + ] } - ] - }, - { - "name": "powder", - "primary": 500, - "white": true, - "include": true, - "stops": [ - { - "stop": 900, - "hex": "1e3c52", - "white": true - }, - { - "stop": 800, - "hex": "2c5777", - "white": true - }, - { - "stop": 700, - "hex": "39739d", - "white": true - }, - { - "stop": 600, - "hex": "5b8db1", - "white": true - }, - { - "stop": 500, - "hex": "7aa7c7", - "white": true - }, - { - "stop": 400, - "hex": "a0c7e4", - "white": true - }, - { - "stop": 300, - "hex": "b3d3ea" - }, - { - "stop": 200, - "hex": "d1e5f1" - }, - { - "stop": 100, - "hex": "e1ecf4" - }, - { - "stop": "050", - "hex": "f4f8fb" + ], + "interaction": [ + { + "name": "Default", + "classes": "" + }, { + "name": "Hover", + "classes": "bg-theme-secondary-500" + }, { + "name": "Selected", + "classes": "bg-theme-secondary-600" + }, { + "name": "Disabled", + "classes": "", + "attr": "disabled" } - ] - }, - { - "name": "black", - "primary": 800, - "white": true, - "include": true, - "stops": [ - { - "stop": 900, - "hex": "0c0d0e", - "white": true - }, - { - "stop": 800, - "hex": "242729", - "white": true - }, - { - "stop": 750, - "hex": "2f3337", - "white": true - }, - { - "stop": 700, - "hex": "3b4045", - "white": true - }, - { - "stop": 600, - "hex": "535a60", - "white": true - }, - { - "stop": 500, - "hex": "6a737c", - "white": true - }, - { - "stop": 400, - "hex": "848d95", - "white": true - }, - { - "stop": 350, - "hex": "9199a1", - "white": true - }, - { - "stop": 300, - "hex": "9fa6ad", - "white": true - }, - { - "stop": 200, - "hex": "bbc0c4" - }, - { - "stop": 150, - "hex": "c8ccd0" - }, - { - "stop": 100, - "hex": "d6d9dc" - }, - { - "stop": "075", - "hex": "e4e6e8" - }, - { - "stop": "050", - "hex": "eff0f1" - }, - { - "stop": "025", - "hex": "fafafb" - } - ] - }, - { - "name": "theme-primary", - "primary": 400, - "white": true, - "stops": [ - { - "stop": 900, - "white": true - }, - { - "stop": 800, - "white": true - }, - { - "stop": 700, - "white": true - }, - { - "stop": 600, - "white": true - }, - { - "stop": 500, - "white": true - }, - { - "stop": 400, - "white": true - }, - { - "stop": 350 - }, - { - "stop": 300 - }, - { - "stop": 200 - }, - { - "stop": 150 - }, - { - "stop": 100 - }, - { - "stop": "075" - }, - { - "stop": "050" - }, - { - "stop": "025" - } - ] - }, - { - "name": "theme-secondary", - "primary": 400, - "white": true, - "stops": [ - { - "stop": 900, - "white": true - }, - { - "stop": 800, - "white": true - }, - { - "stop": 700, - "white": true - }, - { - "stop": 600, - "white": true - }, - { - "stop": 500, - "white": true - }, - { - "stop": 400, - "white": true - }, - { - "stop": 350 - }, - { - "stop": 300 - }, - { - "stop": 200 - }, - { - "stop": 150 - }, - { - "stop": 100 - }, - { - "stop": "075" - }, - { - "stop": "050" - }, - { - "stop": "025" - } - ] - }, - { - "name": "gold", - "primary": "", - "flip": true, - "stops": [ - { - "stop": "darker", - "hex": "f1b600", - "white": true - }, - { - "stop": "", - "hex": "ffcc01", - "flip": true - }, - { - "stop": "lighter", - "hex": "fff4d1" - } - ] - }, - { - "name": "silver", - "primary": "", - "flip": true, - "stops": [ - { - "stop": "darker", - "hex": "9a9c9f", - "white": true - }, - { - "stop": "", - "hex": "b4b8bc", - "flip": true - }, - { - "stop": "lighter", - "hex": "e8e8e8" + ], + "accessibility": [ + { + "heading": "Contrast", + "copy": "Contrast is the difference in luminance or color between any two elements. All visual readers require ample luminance contrast for fluent readability. Based on APCA bronze standards, all text must have a Lightness contrast (Lc) value of 60, body copy must have a Lc value of 75, icons must have a Lc value of 45, and placeholder and disabled text must have a Lc of 30. These numbers will be negative when calculating for dark mode.", + "groups": [ + { + "correct": true, + "text": "Use luminance contrast that meets our standards as defined above.", + "examples": [ + { + "type": "button", + "class": "s-btn s-btn__filled", + "children": "Button" + }, { + "type": "pill", + "class": "bar-pill ta-center px8 py2 bg-green-400 fc-white", + "children": "Robotics" + } + ] + }, { + "correct": false, + "text": "Use low luminance contrast that fail our standards.", + "examples": [ + { + "type": "button", + "class": "s-btn s-btn__filled bg-theme-secondary-200", + "children": "Button" + }, { + "type": "pill", + "class": "bar-pill ta-center px8 py2 bg-green-400 fc-green-300", + "children": "Robotics" + } + ] + } + ] + }, { + "heading": "Visual cues", + "copy": "Visual readers with color vision deficiency (CVD) have problems differentiating some hues and therefore these users need help discerning differences between items. This means that color (hue) should never be the sole means of communicating information and should always be paired with a non-color dependent indicator to accommodate all visual users.", + "groups": [ + { + "correct": true, + "text": "Use an icon alongside color to convey meaning.", + "examples": [ + { + "type": "input", + "stateClass": "has-error" + } + ] + }, { + "correct": false, + "text": "Use color as the only visual cue.", + "examples": [ + { + "type": "input", + "stateClass": "has-error" + } + ] + } + ] } ] }, { - "name": "bronze", - "primary": "", - "flip": true, - "stops": [ - { - "stop": "darker", - "hex": "ab825f", - "white": true - }, - { - "stop": "", - "hex": "caa789", - "flip": true - }, - { - "stop": "lighter", - "hex": "f2e9e1" - } - ] - }, - { - "name": "white", - "primary": "", - "stops": [ - { - "stop": "", - "hex": "ffffff" + "name": "v1", + "status": "deprecated", + "sets": [ + { + "name": "red", + "bg": 500, + "stops": ["025", "050", 100, 200, 300, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 800, 900], + "include": true + }, + { + "name": "orange", + "bg": 600, + "stops": ["050", 100, 200, 300, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 800, 900], + "include": true + }, + { + "name": "yellow", + "bg": 600, + "stops": ["050", 100, 200, 300, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 800, 900], + "include": true + }, + { + "name": "green", + "bg": 600, + "stops": ["025", "050", 100, 200, 300, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 800, 900], + "include": true + }, + { + "name": "blue", + "bg": 600, + "stops": ["050", 100, 200, 300, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 800, 900], + "include": true + }, + { + "name": "powder", + "bg": 600, + "stops": ["050", 100, 200, 300, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 800, 900], + "include": true + }, + { + "name": "black", + "bg": 900, + "stops": ["025", "050", "075", 100, 150, 200, 300, 350, 400, 500, 600, 700, 750, 800, 900, ""], + "invert": [300, 350, 400, 500, 600, 700, 750, 800, 900, ""], + "include": true + }, + { + "name": "theme-primary", + "bg": 500, + "stops": ["025", "050", "075", 100, 150, 200, 300, 350, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 750, 800, 900] + }, + { + "name": "theme-secondary", + "bg": 400, + "stops": ["025", "050", "075", 100, 150, 200, 300, 350, 400, 500, 600, 700, 800, 900], + "invert": [400, 500, 600, 700, 750, 800, 900] + }, + { + "name": "gold", + "bg": "darker", + "fc": "black", + "stops": ["lighter", "", "darker"], + "exclude": { + "hover": ["lighter", "", "darker"], + "focus": ["lighter", "", "darker"], + "dark": ["lighter", "", "darker"], + "class": { + "bc": ["lighter", "", "darker"] + } + }, + "invert": ["darker"] + }, + { + "name": "silver", + "bg": "darker", + "fc": "black", + "stops": ["lighter", "", "darker"], + "exclude": { + "hover": ["lighter", "", "darker"], + "focus": ["lighter", "", "darker"], + "dark": ["lighter", "", "darker"], + "class": { + "bc": ["lighter", "", "darker"] + } + }, + "invert": ["darker"] + }, + { + "name": "bronze", + "bg": "darker", + "fc": "black", + "stops": ["lighter", "", "darker"], + "exclude": { + "hover": ["lighter", "", "darker"], + "focus": ["lighter", "", "darker"], + "dark": ["lighter", "", "darker"], + "class": { + "bc": ["lighter", "", "darker"] + } + }, + "invert": ["darker"] + }, + { + "name": "white", + "bg": "", + "fc": "black", + "stops": [""] } ] } diff --git a/docs/_data/links.json b/docs/_data/links.json index 108b8e840e..2c7468c25b 100755 --- a/docs/_data/links.json +++ b/docs/_data/links.json @@ -61,7 +61,7 @@ "applies": ".s-anchors", "name": "grayscale", "description": "Applies gray styling to all descendent links.", - "exampleClasses": "fc-orange-700" + "exampleClasses": "fc-orange-500" }, { "class": ".s-anchors__muted", @@ -89,7 +89,7 @@ "applies": ".s-anchors", "name": "inherit", "description": "Applies the parent element’s text color to all descendent links.", - "exampleClasses": "fc-green-500" + "exampleClasses": "fc-green-400" } ], "block-links": [ @@ -112,6 +112,11 @@ "class": ".s-block-link__left", "applies": ".s-block-link", "description": "Applies a border to the left of the selected state." + }, + { + "class": ".s-block-link__danger", + "applies": ".s-block-link", + "description": "Applies danger state styling." } ] } \ No newline at end of file diff --git a/docs/_data/site-navigation.json b/docs/_data/site-navigation.json index 1ba099785f..5cd665fbd6 100755 --- a/docs/_data/site-navigation.json +++ b/docs/_data/site-navigation.json @@ -22,16 +22,36 @@ { "title": "JavaScript", "url": "/product/guidelines/javascript/" - }, - { - "title": "Theming", - "url": "/product/guidelines/theming/" } ] }, { - "title": "Resources", + "title": "Design", "links": [ + { + "title": "Color fundamentals", + "url": "/product/base/color-fundamentals/" + }, + { + "title": "Color palette", + "url": "/product/base/colors/" + }, + { + "title": "Color palette (legacy)", + "url": "/product/v1/base/colors/" + }, + { + "title": "Current color", + "url": "/product/base/current-color/" + }, + { + "title": "Theming", + "url": "/product/guidelines/theming/" + }, + { + "title": "Theming (legacy)", + "url": "/product/v1/guidelines/theming/" + }, { "title": "Icons", "url": "/product/resources/icons/" @@ -39,6 +59,10 @@ { "title": "Spot illustrations", "url": "/product/resources/spots/" + }, + { + "title": "Typography", + "url": "/product/base/typography/" } ] }, @@ -65,14 +89,6 @@ "title": "Box sizing", "url": "/product/base/box-sizing/" }, - { - "title": "Colors", - "url": "/product/base/colors/" - }, - { - "title": "Current color", - "url": "/product/base/current-color/" - }, { "title": "Cursors", "url": "/product/base/cursors/" @@ -137,10 +153,6 @@ "title": "Truncation", "url": "/product/base/truncation/" }, - { - "title": "Typography", - "url": "/product/base/typography/" - }, { "title": "Vertical alignment", "url": "/product/base/vertical-alignment/" diff --git a/docs/_data/typography.json b/docs/_data/typography.json index 46eb6f0e40..9ecbd81155 100755 --- a/docs/_data/typography.json +++ b/docs/_data/typography.json @@ -94,8 +94,8 @@ }, { "class": "fw-bold", - "output": "font-weight: 600;", - "define": "

Bold font weight. Maps to 600.

", + "output": "font-weight: 700;", + "define": "

Bold font weight. Maps to 700.

", "responsive": false }, { diff --git a/docs/_includes/color-row-detail.html b/docs/_includes/color-row-detail.html new file mode 100644 index 0000000000..014fed1a04 --- /dev/null +++ b/docs/_includes/color-row-detail.html @@ -0,0 +1,21 @@ +{% assign computedClasses = "" %} +{% assign positionClasses = "mt8 fd-column" %} +{% assign height = 12 %} + +{% if range != true %} + {% assign computedClasses = "w0" %} +{% endif %} +{% if position == "top" %} + {% assign positionClasses = "mb8 fd-column-reverse" %} +{% endif %} +{% if range != true and position != "top" %} + {% assign height = "24" %} +{% endif %} + +
+ {% if range %} +
+ {% endif %} +
+
{{text}}
+
diff --git a/docs/_includes/color-row.html b/docs/_includes/color-row.html new file mode 100644 index 0000000000..7df8771e6c --- /dev/null +++ b/docs/_includes/color-row.html @@ -0,0 +1,27 @@ +{% for set in colorSets %} + {% if set.name == color %} +
+ {% for stop in set.stops %} + {% if stop != "" %} + {% capture stopStr %}{{ stop }}{% endcapture %} + {% assign name = set.name | append: "-" | append: stop | replace: " ", "-" %} + {% assign showClass = " sm:d-none" %} + {% if labeledStops contains stopStr or labeledStops == null %} + {% assign showClass = "" %} + {% endif %} + {% assign stopFc = "fc-medium" %} + {% if set.invert contains stop %} + {% assign stopFc = "fc-white" %} + {% endif %} + +
+ {{ name }} + {% if labeledStops contains stopStr %} +
{{stop | replace: "050", "50"}}
+ {% endif %} +
+ {% endif %} + {% endfor %} +
+ {% endif %} +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/color-swatch.html b/docs/_includes/color-swatch.html new file mode 100644 index 0000000000..9f2a38e1b4 --- /dev/null +++ b/docs/_includes/color-swatch.html @@ -0,0 +1,4 @@ +
+
+ {{text}} +
\ No newline at end of file diff --git a/docs/_includes/header.html b/docs/_includes/header.html index c3667ef003..0ad3a4d78c 100644 --- a/docs/_includes/header.html +++ b/docs/_includes/header.html @@ -50,7 +50,7 @@
  • -

    Stacks provides everything you need to quickly design, build, and ship coherent experiences across all of Stack Overflow—from the brand and product itself, down to how we send emails and write copy.

    -
    +
    diff --git a/docs/_includes/layouts/page.html b/docs/_includes/layouts/page.html index 87ced3d3da..1988fc8b06 100644 --- a/docs/_includes/layouts/page.html +++ b/docs/_includes/layouts/page.html @@ -36,17 +36,17 @@

    {{ title }}

    {% if js %}
    -
    {% icon "Checkmark" %}
    -
    JavaScript
    +
    {% icon "Checkmark" %}
    +
    JavaScript
    {% endif %} {% if figma %} - @@ -104,7 +104,7 @@

    {{ title }}