Skip to content

Commit

Permalink
Document the color-4-api breaking change (#1203)
Browse files Browse the repository at this point in the history
Closes #1197
  • Loading branch information
nex3 authored Sep 23, 2024
1 parent 145f35b commit 2c3452f
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 8 deletions.
1 change: 1 addition & 0 deletions source/_data/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ toc:
- Mixed Declarations: /documentation/breaking-changes/mixed-decls/
- <code>meta.feature-exists</code>: /documentation/breaking-changes/feature-exists/
- Color Functions: /documentation/breaking-changes/color-functions/
- Color JS API: /documentation/breaking-changes/color-4-api/
- Legacy JS API: /documentation/breaking-changes/legacy-js-api/
- Command Line: /documentation/cli/
:children:
Expand Down
23 changes: 15 additions & 8 deletions source/_includes/silencing_deprecations.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ change without creating an overwhelming amount of console noise.

If you run Sass in verbose mode instead, it will print *every* deprecation
warning it encounters. This can be useful for tracking the remaining work to be
done when fixing deprecations. You can enable verbose mode using the
[`--verbose` flag] on the command line, or the [`verbose` option] in the
JavaScript API.
done when fixing deprecations. You can enable verbose mode using
{%- unless jsonly %}
the [`--verbose` flag] on the command line, or
{%- endunless %}
the [`verbose` option] in the JavaScript API.

[`--verbose` flag]: /documentation/cli/dart-sass/#verbose
[`verbose` option]: /documentation/js-api/interfaces/Options/#verbose
Expand All @@ -35,8 +37,11 @@ JavaScript API.

Sometimes, your dependencies have deprecation warnings that you can't do
anything about. You can silence deprecation warnings from dependencies while
still printing them for your app using the [`--quiet-deps` flag] on the command
line, or the [`quietDeps` option] in the JavaScript API.
still printing them for your app using
{%- unless jsonly %}
the [`--quiet-deps` flag] on the command line, or
{%- endunless %}
the [`quietDeps` option] in the JavaScript API.

[`--quiet-deps` flag]: /documentation/cli/dart-sass/#quiet-deps
[`quietDeps` option]: /documentation/js-api/interfaces/Options/#quietDeps
Expand All @@ -49,9 +54,11 @@ importers.
### Silencing Specific Deprecations

If you know that one particular deprecation isn't a problem for you, you can
silence warnings for that specific deprecation using the
[`--silence-deprecation` flag] on the command line, or the [`silenceDeprecations`
option] in the JavaScript API.
silence warnings for that specific deprecation using
{%- unless jsonly %}
the [`--silence-deprecation` flag] on the command line, or
{%- endunless %}
the [`silenceDeprecations` option] in the JavaScript API.

[`--silence-deprecation` flag]: /documentation/cli/dart-sass/#silence-deprecation
[`silenceDeprecations` option]: /documentation/js-api/interfaces/Options/#silenceDeprecations
80 changes: 80 additions & 0 deletions source/documentation/breaking-changes/color-4-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: 'Breaking Change: Color JS API'
introduction: >
Certain aspects of the JS color API that were designed with the assumption
that all colors were mutually compatible no longer make sense now that Sass
supports all the color spaces of CSS Color 4.
---

Just as some aspects of [Sass's color functions are being deprecated] with the
addition of support for [CSS Color 4], some corners of the JS API for
manipulating colors are deprecated as well.

[Sass's color functions are being deprecated]: /documentation/breaking-changes/color-functions
[CSS Color 4]: https://developer.mozilla.org/en-US/blog/css-color-module-level-4/

### `color.change()` now requires a `space` for cross-space changes

Previously, the [`color.change()` method] just took a set of channel names from
the RGB, HSL, or HWB spaces. As long as those channels weren't mixed across
spaces (for example by changing both `red` and `hue` at the same time), Sass
could figure out which space was intended.

[`color.change()` method]: /documentation/js-api/classes/SassColor/#change

With Color 4, color spaces are no longer unambiguous from their channel names
alone. Many spaces have `red`, `green`, and `blue` channels with different
ranges; many spaces have `hue` channels which produce very different color
wheels. To fix this ambiguity, `color.change()` now takes a `space` parameter
which explicitly specifies the name of the color space you want to do the
transformation in:

```js
const color = new sass.SassColor({red: 0x66, green: 0x33, blue: 0x99});
color.change({hue: 270, space: "okclh"});
```

Specifying the color space is mandatory if the color in question isn't in a
[legacy color space] or if you're changing a channel like chroma that only
exists in non-legacy color spaces. It's always optional if you're changing a
channel that exists in the color's own space, so `color.change({red: 0.8})`
always refers to the native red channel of any color with `red`, `green`, and
`blue` channels.

[legacy color space]: /documentation/values/colors#legacy-color-spaces

For backwards-compatibility, if you're changing legacy channels for a legacy
color, Sass will still automatically convert the color for you. However, this
behavior is deprecated. To be safe, you should _always_ pass the `space`
parameter unless you're sure the color is already in the color space whose
channel you want to change.

### `null` channel values

One of the major changes in CSS Color 4 is the new concept of ["missing"
channels]. For example, `hsl(none 0% 40%)` has a missing hue, which is treated
as 0 in most cases but doesn't contribute to color interpolation so that a
gradient with this color won't have a phantom red hue in the middle. When
constructing colors, Sass represents missing values as the value `null`.

["missing" channels]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#missing_color_components

Before adding support for CSS Color 4, the Sass JS API's TypeScript types
forbade the use of `null` in all places where it was relevant. However, the code
itself treated `null` the same as `undefined`, and we don't want to break
compatibility with any plain JavaScript code that was relying on this behavior.
For now, a `null` value is treated as `undefined` and emits a deprecation
warning when constructing a new [legacy color] or calling `color.change()` for a
legacy color. In either case, if you pass a `space` parameter explicitly, you'll
opt into the new behavior and `null` will be treated as a missing channel.

## Transition Period

{% compatibility 'dart: "1.79.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %}

First, we'll emit deprecation warnings for all uses of these APIs that are
slated to be changed. In Dart Sass 2.0.0, the breaking changes will go into
effect fully, and the old behavior will no longer work how it used to.

{% render 'silencing_deprecations', jsonly: true %}

4 changes: 4 additions & 0 deletions source/documentation/breaking-changes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ These breaking changes are coming soon or have recently been released:
* [The legacy JS API](/documentation/breaking-changes/legacy-js-api/) beginning
in Dart Sass 1.79.0.

* [Certain uses of the JS color API are
deprecated](/documentation/breaking-changes/color-4-api/) beginning in Dart
Sass 1.79.0.

* [A number of color functions are
deprecated](/documentation/breaking-changes/color-functions/) beginning in
Dart Sass 1.79.0, in favor of new CSS Color 4-compatible functions.
Expand Down

0 comments on commit 2c3452f

Please sign in to comment.