Skip to content

Commit

Permalink
Support define CSS variables and use CSS variables (#492)
Browse files Browse the repository at this point in the history
  • Loading branch information
davesnx authored Jul 10, 2024
1 parent ab3b122 commit dd210dc
Show file tree
Hide file tree
Showing 34 changed files with 536 additions and 331 deletions.
2 changes: 2 additions & 0 deletions e2e/melange/src/ui/ui.re
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
let c = CSS.color(`var({js|--color-link|js}));

[%styled.global
{|
div {
Expand Down
8 changes: 4 additions & 4 deletions packages/css-property-parser/lib/Combinator.re
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ let rec match_longest = ((left_key, left_rule), rules) =>
};
};

let combine_static = rules => {
let static = rules => {
let rec match_everything = (values, rules) =>
switch (rules) {
| [] => return_match(values |> List.rev)
Expand All @@ -30,7 +30,7 @@ let combine_static = rules => {
match_everything([], rules);
};

let combine_xor =
let xor =
fun
| [] => failwith("xor doesn't makes sense without a single value")
| [left, ...rules] => {
Expand All @@ -40,7 +40,7 @@ let combine_xor =
value;
};

let combine_and = rules => {
let and_ = rules => {
// TODO: an array is a better choice
let rec match_everything = (values, rules) =>
switch (rules) {
Expand All @@ -59,4 +59,4 @@ let combine_and = rules => {
};

// [ A || B ] = [ A? && B? ]!
let combine_or = rules => rules |> List.map(optional) |> combine_and;
let or_ = rules => rules |> List.map(optional) |> and_;
8 changes: 4 additions & 4 deletions packages/css-property-parser/lib/Combinator.rei
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
type combinator('a, 'b) = list(Rule.rule('a)) => Rule.rule('b);

// TODO: docs for infix operators
let combine_static: combinator('a, list('a));
let static: combinator('a, list('a));

let combine_xor: combinator('a, 'a);
let xor: combinator('a, 'a);

let combine_and: combinator('a, list('a));
let and_: combinator('a, list('a));

let combine_or: combinator('a, list(option('a)));
let or_: combinator('a, list(option('a)));
7 changes: 7 additions & 0 deletions packages/css-property-parser/lib/Modifier.rei
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ type modifier('a, 'b) = Rule.rule('a) => Rule.rule('b);
type range = (int, option(int));

let one: modifier('a, 'a);

let optional: modifier('a, option('a));

let zero_or_more: modifier('a, list('a));

let one_or_more: modifier('a, list('a));

let repeat: range => modifier('a, list('a));

let repeat_by_comma: range => modifier('a, list('a));

let at_least_one: modifier(list(option('a)), list(option('a)));

let at_least_one_2:
modifier((option('a), option('b)), (option('a), option('b)));
57 changes: 49 additions & 8 deletions packages/css-property-parser/lib/Parser.re
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
open Standard;
open Combinator;
open Modifier;
open Rule.Match;
open Parser_helper;
open Styled_ppx_css_parser;

module StringMap = Map.Make(String);

let (let.ok) = Result.bind;

let rec _legacy_gradient = [%value.rec
"<-webkit-gradient()> | <-legacy-linear-gradient> | <-legacy-repeating-linear-gradient> | <-legacy-radial-gradient> | <-legacy-repeating-radial-gradient>"
]
Expand Down Expand Up @@ -1956,6 +1958,51 @@ and wq_name = [%value.rec "[ <ns-prefix> ]? <ident-token>"]
and x = [%value.rec "<number>"]
and y = [%value.rec "<number>"];

let apply_parser = (parser, tokens_with_loc) => {
open Styled_ppx_css_parser.Lexer;

let tokens =
tokens_with_loc
|> List.map(({txt, _}) =>
switch (txt) {
| Ok(token) => token
| Error((token, _)) => token
}
)
|> List.rev;

let tokens_without_ws = tokens |> List.filter((!=)(Tokens.WS));

let (output, remaining_tokens) = parser(tokens_without_ws);
let.ok output =
switch (output) {
| Ok(data) => Ok(data)
| Error([message, ..._]) => Error(message)
| Error([]) => Error("weird")
};
let.ok () =
switch (remaining_tokens) {
| []
| [Tokens.EOF] => Ok()
| tokens =>
let tokens =
tokens |> List.map(Tokens.show_token) |> String.concat(", ");
Error("tokens remaining: " ++ tokens);
};
Ok(output);
};

let parse = (rule_parser: Rule.rule('a), str) => {
let.ok tokens_with_loc =
Styled_ppx_css_parser.Lexer.from_string(str)
|> Result.map_error(_ => "frozen");

apply_parser(rule_parser, tokens_with_loc);
};

let check = (prop: Rule.rule('a), value) =>
parse(prop, value) |> Result.is_ok;

let check_map =
StringMap.of_seq(
List.to_seq([
Expand Down Expand Up @@ -3397,12 +3444,6 @@ let check_map =
]),
);

let parse = Parser_helper.parse;

module StringMap = Map.Make(String);

let (let.ok) = Result.bind;

let check_value = (~name, value) => {
let.ok check =
check_map
Expand Down
75 changes: 0 additions & 75 deletions packages/css-property-parser/lib/Parser_helper.re

This file was deleted.

38 changes: 32 additions & 6 deletions packages/css-property-parser/lib/Standard.re
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
open Styled_ppx_css_parser.Tokens;
open Combinator;
open Rule.Let;
open Rule.Pattern;

Expand All @@ -12,9 +11,7 @@ let function_call = (name, rule) => {
fun
| FUNCTION(called_name) when name == called_name => Ok()
| token =>
Error([
"expected a function " ++ name ++ ". got an " ++ show_token(token),
]),
Error(["expected a " ++ name ++ ". got an " ++ show_token(token)]),
);
let.bind_match value = rule;
let.bind_match () = expect(RIGHT_PAREN);
Expand Down Expand Up @@ -160,7 +157,7 @@ let ident =

// https://drafts.csswg.org/css-values-4/#textual-values
let css_wide_keywords =
combine_xor([
Combinator.xor([
value(`Initial, keyword("initial")),
value(`Inherit, keyword("inherit")),
value(`Unset, keyword("unset")),
Expand Down Expand Up @@ -204,9 +201,12 @@ let url = {
| _ => Error(["expected a url"]),
);
let url_fun = function_call("url", string);
combine_xor([url_token, url_fun]);
Combinator.xor([url_token, url_fun]);
};

// https://drafts.csswg.org/css-variables-2/#funcdef-var
/* let var = function_call("var", dashed_ident); */

// css-color-4
// https://drafts.csswg.org/css-color-4/#hex-notation
let hex_color =
Expand Down Expand Up @@ -267,3 +267,29 @@ let flex_value =
}
| _ => Error(["expected flex_value"]),
);

// TODO: workarounds
let invalid = expect(STRING("not-implemented"));
let attr_name = invalid;
let attr_fallback = invalid;
let string_token = invalid;
let ident_token = invalid;
let dimension = invalid;
let declaration_value = invalid;
let positive_integer = integer;
let function_token = invalid;
let any_value = invalid;
let hash_token = invalid;
let zero = invalid;
let custom_property_name = invalid;
let declaration_list = invalid;
let name_repeat = invalid;
let ratio = invalid;
let an_plus_b = invalid;
let declaration = invalid;
let y = invalid;
let x = invalid;
let decibel = invalid;
let urange = invalid;
let semitones = invalid;
let url_token = invalid;
Loading

0 comments on commit dd210dc

Please sign in to comment.