Skip to content

Commit 9c5b9d6

Browse files
committed
Code review
1 parent 90439ed commit 9c5b9d6

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

lib/src/value/color.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,28 @@
33
// https://opensource.org/licenses/MIT.
44

55
import {Value} from './value';
6-
import {fuzzyAssertInRange, fuzzyEquals, fuzzyRound} from './utils';
6+
import {fuzzyAssertInRange, fuzzyEquals, fuzzyRound, positiveMod} from './utils';
77
import {hash} from 'immutable';
88

99
interface RgbColor {
1010
red: number;
1111
green: number;
1212
blue: number;
13-
alpha: number;
13+
alpha?: number;
1414
}
1515

1616
interface HslColor {
1717
hue: number;
1818
saturation: number;
1919
lightness: number;
20-
alpha: number;
20+
alpha?: number;
2121
}
2222

2323
interface HwbColor {
2424
hue: number;
2525
whiteness: number;
2626
blackness: number;
27-
alpha: number;
27+
alpha?: number;
2828
}
2929

3030
/** A SassScript color. */
@@ -37,6 +37,9 @@ export class SassColor extends Value {
3737
private lightnessInternal?: number;
3838
private readonly alphaInternal: number;
3939

40+
constructor(color: RgbColor);
41+
constructor(color: HslColor);
42+
constructor(color: HwbColor);
4043
constructor(color: RgbColor | HslColor | HwbColor) {
4144
super();
4245

@@ -60,7 +63,7 @@ export class SassColor extends Value {
6063
'blue'
6164
);
6265
} else if ('saturation' in color) {
63-
this.hueInternal = color.hue % 360;
66+
this.hueInternal = positiveMod(color.hue, 360);
6467
this.saturationInternal = fuzzyAssertInRange(
6568
color.saturation,
6669
0,
@@ -75,7 +78,7 @@ export class SassColor extends Value {
7578
);
7679
} else {
7780
// From https://www.w3.org/TR/css-color-4/#hwb-to-rgb
78-
const scaledHue = (color.hue % 360) / 360;
81+
const scaledHue = positiveMod(color.hue, 360) / 360;
7982
let scaledWhiteness =
8083
fuzzyAssertInRange(color.whiteness, 0, 100, 'whiteness') / 100;
8184
let scaledBlackness =
@@ -91,13 +94,13 @@ export class SassColor extends Value {
9194
// don't cache its values because we expect the memory overhead of doing so
9295
// to outweigh the cost of recalculating it on access. Instead, we eagerly
9396
// convert it to RGB and then convert back if necessary.
94-
this.redInternal = toRgb(
97+
this.redInternal = hwbToRgb(
9598
scaledHue + 1 / 3,
9699
scaledWhiteness,
97100
scaledBlackness
98101
);
99-
this.greenInternal = toRgb(scaledHue, scaledWhiteness, scaledBlackness);
100-
this.blueInternal = toRgb(
102+
this.greenInternal = hwbToRgb(scaledHue, scaledWhiteness, scaledBlackness);
103+
this.blueInternal = hwbToRgb(
101104
scaledHue - 1 / 3,
102105
scaledWhiteness,
103106
scaledBlackness
@@ -186,6 +189,9 @@ export class SassColor extends Value {
186189
/**
187190
* Returns a copy of `this` with its channels changed to match `color`.
188191
*/
192+
change(color: Partial<RgbColor>): SassColor;
193+
change(color: Partial<HslColor>): SassColor;
194+
change(color: Partial<HwbColor>): SassColor;
189195
change(
190196
color: Partial<RgbColor> | Partial<HslColor> | Partial<HwbColor>
191197
): SassColor {
@@ -270,11 +276,11 @@ export class SassColor extends Value {
270276
if (max === min) {
271277
this.hueInternal = 0;
272278
} else if (max === scaledRed) {
273-
this.hueInternal = ((60 * (scaledGreen - scaledBlue)) / delta) % 360;
279+
this.hueInternal = positiveMod((60 * (scaledGreen - scaledBlue)) / delta, 360);
274280
} else if (max === scaledGreen) {
275-
this.hueInternal = (120 + (60 * (scaledBlue - scaledRed)) / delta) % 360;
281+
this.hueInternal = positiveMod(120 + (60 * (scaledBlue - scaledRed)) / delta, 360);
276282
} else if (max === scaledBlue) {
277-
this.hueInternal = (240 + (60 * (scaledRed - scaledGreen)) / delta) % 360;
283+
this.hueInternal = positiveMod(240 + (60 * (scaledRed - scaledGreen)) / delta, 360);
278284
}
279285

280286
this.lightnessInternal = 50 * (max + min);
@@ -312,7 +318,7 @@ export class SassColor extends Value {
312318
}
313319

314320
// A helper for converting HWB colors to RGB.
315-
function toRgb(hue: number, scaledWhiteness: number, scaledBlackness: number) {
321+
function hwbToRgb(hue: number, scaledWhiteness: number, scaledBlackness: number) {
316322
const factor = 1 - scaledWhiteness - scaledBlackness;
317323
const channel = hueToRgb(0, 1, hue) * factor + scaledWhiteness;
318324
return fuzzyRound(channel * 255);

lib/src/value/list.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ export class SassList extends Value {
3131
* Returns a list that contains `contents`, with the given `separator` and
3232
* `brackets`.
3333
*/
34+
constructor(
35+
contents: Value[] | List<Value>,
36+
options?: {
37+
separator?: ListSeparator;
38+
brackets?: boolean;
39+
}
40+
);
41+
constructor(options?: {separator?: ListSeparator; brackets?: boolean});
3442
constructor(
3543
contentsOrOptions?: Value[] | List<Value> | ConstructorOptions,
3644
options?: ConstructorOptions

lib/src/value/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,9 @@ export function fuzzyAssertInRange(
114114
if (num > min && num < max) return num;
115115
throw valueError(`${num} must be between ${min} and ${max}`, name);
116116
}
117+
118+
/** Returns `dividend % modulus`, but always in the range `[0, modulus)`. */
119+
export function positiveMod(dividend: number, modulus: number) {
120+
const result = dividend % modulus;
121+
if (result < 0) return modulus + result;
122+
}

0 commit comments

Comments
 (0)