Skip to content

Commit

Permalink
reworked the calc function (#271)
Browse files Browse the repository at this point in the history
  • Loading branch information
giraud committed Oct 16, 2023
1 parent 1530d0a commit 1d9c41d
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 298 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ npm-debug.log
*.js
*.log

.pnp.*
.yarn/*
!.yarn/releases
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.pnp.*
24 changes: 22 additions & 2 deletions bs-css/__tests__/Css_Js_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ let toBe = (e, x) => Jest.toBe(e, x->Js.Json.stringifyAny)
let expect = x =>
Jest.expect(toJson([x])->Js.Json.stringifyAny) /* simple rule for more readable tests */

describe("Height", () => {
test("test usage", () => {
expect(height(pct(80.)))->toBe({"height": "80%"})
expect(height(px(80)))->toBe({"height": "80px"})
expect(height(auto))->toBe({"height": "auto"})
expect(height(fitContent))->toBe({"height": "fit-content"})
expect(height(maxContent))->toBe({"height": "max-content"})
expect(height(minContent))->toBe({"height": "min-content"})
expect(height(#sub(pct(100.), px(20))))->toBe({"height": "calc(100% - 20px)"})
expect(height(var("--foo")))->toBe({"height": "var(--foo)"})
})
})

describe("Var", () => {
test("test usage (limited)", () => {
expect(color(var("foo")))->toBe({"color": "var(--foo)"})
Expand Down Expand Up @@ -133,8 +146,10 @@ describe("Gradient background", () =>
expect(background(radialGradient([(zero, red), (pct(100.), blue)])))->toBe({
"background": "radial-gradient(#FF0000 0, #0000FF 100%)",
})
open Calc
expect(background(repeatingRadialGradient([(zero, red), (pct(20.) + px(5), blue)])))->toBe({
// open Calc
expect(
background(repeatingRadialGradient([(zero, red), (#add(pct(20.), px(5)), blue)])),
)->toBe({
"background": "repeating-radial-gradient(#FF0000 0, #0000FF calc(20% + 5px))",
})
expect(background(conicGradient(deg(45.), [(zero, red), (pct(100.), blue)])))->toBe({
Expand Down Expand Up @@ -350,6 +365,11 @@ describe("gridTemplateColumns", () => {
expect(gridTemplateColumns([#repeat((#num(4), #minmax((#px(100), #fr(1.)))))]))->toBe({
"gridTemplateColumns": "repeat(4, minmax(100px,1fr))",
})
expect(
gridTemplateColumns([#repeat((#num(4), #minmax((#px(100), #add(#percent(80.), #px(10))))))]),
)->toBe({
"gridTemplateColumns": "repeat(4, minmax(100px,calc(80% + 10px)))",
})
})
})

Expand Down
6 changes: 4 additions & 2 deletions bs-css/__tests__/Css_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,10 @@ describe("Gradient background", () =>
expect(background(radialGradient([(zero, red), (pct(100.), blue)])))->toBe({
"background": "radial-gradient(#FF0000 0, #0000FF 100%)",
})
open Calc
expect(background(repeatingRadialGradient([(zero, red), (pct(20.) + px(5), blue)])))->toBe({
// open Calc
expect(
background(repeatingRadialGradient([(zero, red), (#add(pct(20.), px(5)), blue)])),
)->toBe({
"background": "repeating-radial-gradient(#FF0000 0, #0000FF calc(20% + 5px))",
})
expect(background(conicGradient(deg(45.), [(zero, red), (pct(100.), blue)])))->toBe({
Expand Down
37 changes: 25 additions & 12 deletions bs-css/src/Css_AtomicTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module Url = {
}

module Length = {
type rec t = [
type t = [
| #ch(float)
| #em(float)
| #ex(float)
Expand All @@ -89,7 +89,6 @@ module Length = {
| #pc(float)
| #pt(int)
| #zero
| #calc([#add | #sub | #mult], t, t)
| #percent(float)
]

Expand All @@ -110,7 +109,7 @@ module Length = {
let pt = x => #pt(x)
let zero = #zero

let rec toString = x =>
let toString = x =>
switch x {
| #ch(x) => Js.Float.toString(x) ++ "ch"
| #em(x) => Js.Float.toString(x) ++ "em"
Expand All @@ -128,13 +127,24 @@ module Length = {
| #pc(x) => Js.Float.toString(x) ++ "pc"
| #pt(x) => Js.Int.toString(x) ++ "pt"
| #zero => "0"
| #calc(#add, a, b) => "calc(" ++ toString(a) ++ " + " ++ toString(b) ++ ")"
| #calc(#sub, a, b) => "calc(" ++ toString(a) ++ " - " ++ toString(b) ++ ")"
| #calc(#mult, a, b) => "calc(" ++ toString(a) ++ " * " ++ toString(b) ++ ")"
| #percent(x) => Js.Float.toString(x) ++ "%"
}
}

module PercentageLengthCalc = {
type rec t = [Percentage.t | Length.t | #add(t, t) | #sub(t, t) | #mul(t, float) | #div(t, float)]

let rec toString = x =>
switch x {
| #...Percentage.t as p => Percentage.toString(p)
| #...Length.t as l => Length.toString(l)
| #add(a, b) => "calc(" ++ toString(a) ++ " + " ++ toString(b) ++ ")"
| #sub(a, b) => "calc(" ++ toString(a) ++ " - " ++ toString(b) ++ ")"
| #mul(a, b) => "calc(" ++ toString(a) ++ " * " ++ Js.Float.toString(b) ++ ")"
| #div(a, b) => "calc(" ++ toString(a) ++ " / " ++ Js.Float.toString(b) ++ ")"
}
}

module Angle = {
type t = [#deg(float) | #rad(float) | #grad(float) | #turn(float)]

Expand Down Expand Up @@ -1670,11 +1680,14 @@ module OverflowWrap = {

module Gradient = {
type t<'colorOrVar> = [
| #linearGradient(Angle.t, array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingLinearGradient(Angle.t, array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #radialGradient(array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingRadialGradient(array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #conicGradient(Angle.t, array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #linearGradient(Angle.t, array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingLinearGradient(
Angle.t,
array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>,
)
| #radialGradient(array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingRadialGradient(array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #conicGradient(Angle.t, array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
]

let linearGradient = (angle, stops) => #linearGradient((angle, stops))
Expand All @@ -1690,7 +1703,7 @@ module Gradient = {
}
let string_of_stops = stops =>
stops
->Belt.Array.map(((l, c)) => string_of_color(c) ++ " " ++ Length.toString(l))
->Belt.Array.map(((l, c)) => string_of_color(c) ++ " " ++ PercentageLengthCalc.toString(l))
->Js.Array2.joinWith(", ")

let toString = x =>
Expand Down
39 changes: 25 additions & 14 deletions bs-css/src/Css_AtomicTypes.resi
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ module Url: {
https://developer.mozilla.org/docs/Web/CSS/length
*/
module Length: {
// calc/percent are incorrect

/* * The <length> CSS data type represents a distance value. */
type rec t = [
type t = [
| #ch(float)
| #em(float)
| #ex(float)
Expand All @@ -78,7 +76,6 @@ module Length: {
| #pc(float)
| #pt(int)
| #zero
| #calc([#add | #sub | #mult], t, t)
| #percent(float)
]

Expand Down Expand Up @@ -117,6 +114,12 @@ module Length: {
let toString: t => string
}

module PercentageLengthCalc: {
type rec t = [Percentage.t | Length.t | #add(t, t) | #sub(t, t) | #mul(t, float) | #div(t, float)]

let toString: t => string
}

module Angle: {
/**
The angle CSS data type represents an angle value expressed in degrees, gradians, radians, or turns.
Expand Down Expand Up @@ -1173,34 +1176,42 @@ module OverflowWrap: {
*/
module Gradient: {
type t<'colorOrVar> = [
| #linearGradient(Angle.t, array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingLinearGradient(Angle.t, array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #radialGradient(array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingRadialGradient(array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #conicGradient(Angle.t, array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #linearGradient(Angle.t, array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingLinearGradient(
Angle.t,
array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>,
)
| #radialGradient(array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #repeatingRadialGradient(array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
| #conicGradient(Angle.t, array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>)
]

/* * Linear gradients transition colors progressively along an imaginary line. */
let linearGradient: (
Angle.t,
array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>,
array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>,
) => [> t<'colorOrVar>]
/* * Radial gradients transition colors progressively from a center point (origin). */
let radialGradient: array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)> => [> t<'colorOrVar>]
let radialGradient: array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)> => [>
| t<'colorOrVar>
]

/* * Repeating gradients duplicate a gradient as much as necessary to fill a given area (linearGradient function). */
let repeatingLinearGradient: (
Angle.t,
array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>,
array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>,
) => [> t<'colorOrVar>]
/* * Repeating gradients duplicate a gradient as much as necessary to fill a given area (radialGradient function). */
let repeatingRadialGradient: array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)> => [>
let repeatingRadialGradient: array<(
PercentageLengthCalc.t,
[< Color.t | Var.t] as 'colorOrVar,
)> => [>
| t<'colorOrVar>
]
/* * Conic gradients transition colors rotated around a center point */
let conicGradient: (
Angle.t,
array<(Length.t, [< Color.t | Var.t] as 'colorOrVar)>,
array<(PercentageLengthCalc.t, [< Color.t | Var.t] as 'colorOrVar)>,
) => [> t<'colorOrVar>]

let toString: t<[< Color.t | Var.t]> => string
Expand Down
Loading

0 comments on commit 1d9c41d

Please sign in to comment.