Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support define CSS variables and use CSS variables #492

Merged
merged 10 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading