Skip to content

Commit

Permalink
Properly use Value.HasCalculation in CSS values (#1491)
Browse files Browse the repository at this point in the history
* Proprely use Value.HasCalculation

* Add changeset
  • Loading branch information
Jym77 authored Oct 25, 2023
1 parent 49c7384 commit b5e99a2
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 66 deletions.
5 changes: 5 additions & 0 deletions .changeset/thin-melons-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@siteimprove/alfa-css": minor
---

**Breaking:** CSS `Value` types no longer accept a `CALC` parameter; it is automatically inferred
44 changes: 18 additions & 26 deletions packages/alfa-css/src/value/collection/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,24 @@ const { delimited, option, map, separatedList } = Parser;
/**
* @public
*/
export class List<V extends Value, CALC extends boolean = boolean>
extends Value<"list", CALC>
export class List<V extends Value>
extends Value<"list", Value.HasCalculation<[V]>>
implements
Iterable<V>,
Resolvable<List<Resolvable.Resolved<V>, false>, Resolvable.Resolver<V>>
Resolvable<List<Resolvable.Resolved<V>>, Resolvable.Resolver<V>>
{
public static of<V extends Value>(
values: Iterable<V>,
separator = " "
): List<V, Value.HasCalculation<[V]>> {
const array = Array.from(values);
return new List(array, separator, Value.hasCalculation(...array));
separator = " ",
): List<V> {
return new List(Array.from(values), separator);
}

private readonly _values: Array<V>;
private readonly _separator: string;

private constructor(values: Array<V>, separator: string, calculation: CALC) {
super("list", calculation);
private constructor(values: Array<V>, separator: string) {
super("list", Value.hasCalculation(...values));
this._values = values;
this._separator = separator;
}
Expand All @@ -42,22 +41,15 @@ export class List<V extends Value, CALC extends boolean = boolean>
}

public resolve(
resolver?: Resolvable.Resolver<V>
): List<Resolvable.Resolved<V>, false> {
resolver?: Resolvable.Resolver<V>,
): List<Resolvable.Resolved<V>> {
return this.map(
(value) => value.resolve(resolver) as Resolvable.Resolved<V>
(value) => value.resolve(resolver) as Resolvable.Resolved<V>,
);
}

public map<U extends Value>(
mapper: Mapper<V, U>
): List<U, U extends Value<string, false> ? false : true> {
const array = this._values.map(mapper);
const calculation = array.some((value) =>
value.hasCalculation()
) as U extends Value<string, false> ? false : true;

return new List(array, this._separator, calculation);
public map<U extends Value>(mapper: Mapper<V, U>): List<U> {
return new List(this._values.map(mapper), this._separator);
}

public equals<T extends Value>(value: List<T>): boolean;
Expand Down Expand Up @@ -88,7 +80,7 @@ export class List<V extends Value, CALC extends boolean = boolean>
return {
...super.toJSON(),
values: this._values.map(
(value) => value.toJSON() as Serializable.ToJSON<V>
(value) => value.toJSON() as Serializable.ToJSON<V>,
),
separator: this._separator,
};
Expand Down Expand Up @@ -121,11 +113,11 @@ export namespace List {
separator: string,
parseSeparator: CSSParser<any>,
lower: number,
upper: number
upper: number,
): CSSParser<List<V>> {
return map(
separatedList(parseValue, parseSeparator, lower, upper),
(values) => List.of(values, separator)
(values) => List.of(values, separator),
);
}

Expand All @@ -136,12 +128,12 @@ export namespace List {
export const parseCommaSeparated = <V extends Value>(
parseValue: CSSParser<V>,
lower: number = 1,
upper: number = Infinity
upper: number = Infinity,
) => parse(parseValue, ", ", parseComma, lower, upper);

export const parseSpaceSeparated = <V extends Value>(
parseValue: CSSParser<V>,
lower: number = 1,
upper: number = Infinity
upper: number = Infinity,
) => parse(parseValue, " ", parseSpace, lower, upper);
}
29 changes: 12 additions & 17 deletions packages/alfa-css/src/value/collection/tuple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,28 @@ import { Value } from "../value";
/**
* @public
*/
export class Tuple<T extends Array<Value>, CALC extends boolean = boolean>
extends Value<"tuple", CALC>
implements Resolvable<Tuple<Tuple.Resolved<T>, false>, Tuple.Resolver<T>>
export class Tuple<T extends Array<Value>>
extends Value<"tuple", Value.HasCalculation<T>>
implements Resolvable<Tuple<Tuple.Resolved<T>>, Tuple.Resolver<T>>
{
public static of<T extends Array<Value>>(
...values: Readonly<T>
): Tuple<T, Value.HasCalculation<T>> {
return new Tuple(values, Value.hasCalculation(...values));
public static of<T extends Array<Value>>(...values: Readonly<T>): Tuple<T> {
return new Tuple(values);
}

private readonly _values: Readonly<T>;

private constructor(values: Readonly<T>, calculation: CALC) {
super("tuple", calculation);
private constructor(values: Readonly<T>) {
super("tuple", Value.hasCalculation(...values));
this._values = values;
}

public get values(): Readonly<T> {
return this._values;
}

public resolve(
resolver?: Tuple.Resolver<T>
): Tuple<Tuple.Resolved<T>, false> {
return new Tuple<Tuple.Resolved<T>, false>(
public resolve(resolver?: Tuple.Resolver<T>): Tuple<Tuple.Resolved<T>> {
return new Tuple<Tuple.Resolved<T>>(
this._values.map((value) => value.resolve(resolver)) as Tuple.Resolved<T>,
false
);
}

Expand Down Expand Up @@ -61,7 +56,7 @@ export class Tuple<T extends Array<Value>, CALC extends boolean = boolean>
return {
...super.toJSON(),
values: this._values.map((value) =>
value.toJSON()
value.toJSON(),
) as Serializable.ToJSON<T>,
};
}
Expand All @@ -80,7 +75,7 @@ export namespace Tuple {
}

export function isTuple<T extends Array<Value>>(
value: unknown
value: unknown,
): value is Tuple<T> {
return value instanceof Tuple;
}
Expand All @@ -94,7 +89,7 @@ export namespace Tuple {
*/
export type Resolved<T extends Array<Value>> = T extends [
infer Head extends Value,
...infer Tail extends Array<Value>
...infer Tail extends Array<Value>,
]
? [Resolvable.Resolved<Head>, ...Resolved<Tail>]
: [];
Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-css/src/value/resolvable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export namespace Resolvable {
*/
export type Resolved<V extends Value> = V extends Resolvable<infer U, unknown>
? U
: V;
: never;

/**
* @privateRemarks
Expand Down
35 changes: 13 additions & 22 deletions packages/alfa-css/src/value/shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,25 @@ export class Shadow<
B extends Length = Length,
S extends Length = Length,
C extends Color = Color,
CALC extends boolean = boolean
>
extends Value<"shadow", CALC>
extends Value<"shadow", Value.HasCalculation<[H, V, B, S, C]>>
implements Resolvable<Shadow.Canonical, Shadow.Resolver>
{
public static of<
H extends Length = Length,
V extends Length = H,
B extends Length = Length,
S extends Length = Length,
C extends Color = Color
C extends Color = Color,
>(
horizontal: H,
vertical: V,
blur: B,
spread: S,
color: C,
isInset: boolean
): Shadow<H, V, B, S, C, Value.HasCalculation<[H, V, B, S]>> {
return new Shadow(
horizontal,
vertical,
blur,
spread,
color,
isInset,
Value.hasCalculation(horizontal, vertical, blur, spread)
);
isInset: boolean,
): Shadow<H, V, B, S, C> {
return new Shadow(horizontal, vertical, blur, spread, color, isInset);
}

private readonly _horizontal: H;
Expand All @@ -65,9 +56,11 @@ export class Shadow<
spread: S,
color: C,
isInset: boolean,
hasCalculation: CALC
) {
super("shadow", hasCalculation);
super(
"shadow",
Value.hasCalculation(horizontal, vertical, blur, spread, color),
);
this._horizontal = horizontal;
this._vertical = vertical;
this._blur = blur;
Expand Down Expand Up @@ -108,7 +101,6 @@ export class Shadow<
this._spread.resolve(resolver),
this._color.resolve(),
this._isInset,
false
);
}
public equals(value: unknown): value is this {
Expand Down Expand Up @@ -161,8 +153,7 @@ export namespace Shadow {
Length.Canonical,
Length.Canonical,
Length.Canonical,
Color.Canonical,
false
Color.Canonical
>;
export interface JSON extends Value.JSON<"shadow"> {
horizontal: Length.JSON;
Expand All @@ -188,7 +179,7 @@ export namespace Shadow {
: [T, T, T, T];

function checkLength<T, N extends 3 | 4>(
max: N
max: N,
): (array: Array<T>) => array is Sized<T, N> {
return (array): array is Sized<T, N> =>
array.length >= 2 && array.length <= max;
Expand All @@ -198,7 +189,7 @@ export namespace Shadow {
return parseIf(
checkLength<Length, N>(max),
separatedList(Length.parse, Token.parseWhitespace),
() => `Shadows must have between 2 and ${max} lengths`
() => `Shadows must have between 2 and ${max} lengths`,
);
}

Expand Down Expand Up @@ -273,7 +264,7 @@ export namespace Shadow {
blur ?? Length.of(0, "px"),
spread ?? Length.of(0, "px"),
color ?? Keyword.of("currentcolor"),
isInset ?? false
isInset ?? false,
),
]);
};
Expand Down

0 comments on commit b5e99a2

Please sign in to comment.