Skip to content

Idea: Assembler Functions #18

Description

@Explosion-Scratch

Okok, here's the idea: Functions, these would work similarly to built in CSS functions, like calc(), var() and more. So here's how this work work:

:root {
	--dark--function: "@${0}-{1=700}";
}

Now it would be used like this:

<!-- New keyword, just like we use "@" for variables and "^" for mixins, we can use "$" for functions -->
<div x-style="color: $dark(blue, 800);"></div>

Sound cool yet? (not really)

So here's how it gets super cool:

AssemblerCSS.registerFunction("darken", (settings, ...args) => {
  //Same callback format as registerMixin
  var color = args[0];
  var amount = args[1];
  if (!(color && amount)) return args.join(",");//Return the original args and stuff
  if (!+amount) return color;//Return the color if amount isn't a number
  if (!/^#[0-9A-F]{6}$/i.test(color)) {
    //Since this is just a code sample for an idea I'm not gonna add color conversion and stuff.
    return color;
  }
  return `#${darkenHex(color.replace(/^#/, "").toUpperCase(), amount)}`;
  function darkenHex(col, amt) {
    amt = 0 - amt;//We're darkening, not lightning
    var num = parseInt(col, 16);
    var r = (num >> 16) + amt;
    var b = ((num >> 8) & 0x00ff) + amt;
    var g = (num & 0x0000ff) + amt;
    var newColor = g | (b << 8) | (r << 16);
    return newColor.toString(16);
  }
});

Nowwww, look what we could do (!!!)

<div x-style="color: darken(#345beb, 20)"></div>

which turns into...

<div x-style="color: #2047d7"></div>

There are endless possibilities with this! Please consider adding it! 😃

Activity

  1. Awilum commented on Sep 13, 2021

    @Awilum
    Contributor

    Looks similar to Mixins, except, we don't need to use this special char ^ in x-style for functions

  2. msarca commented on Sep 13, 2021

    @msarca
    Member

    How about this example?

    box-shadow: 0 0 4px $alpha($darken(rgba(255, 100, 5, var(--alpha, 1)), 20), 80), 
                0 0 8px var(--color, $darken($alpha(hsla(100, 100%, 50%, var(--alpha, 1)), 80), 20));

    Not only that you need to evaluate var(--alpha), but you also need to evaluate rgba and hsla yourself. Moreover, $darken and $alpha need to be evaluated in a specific order because the value they return is used as an argument for other functions. This is fine for SCSS, which compiles everything ahead-of-time, but the parser of Assembler CSS works in real-time.

    We already had this discussion and made some tests with @sorinsarca months ago, and this kind of functionality would have a tremendous impact on the performance. However, for the simple usage example you are presenting here, using a mixin can be enough.

    registerMixin('darken', color, value, property) {
        property = property || 'color';
        return `${property}: ${darken(color, value)}`;
    }
    
    function darken(color, value) {
       // ...
    }

    Usage

    ^darken: #ff0fab, 20; ^darken: #ff00ff, 30, background-color;
  3. Explosion-Scratch commented on Sep 13, 2021

    @Explosion-Scratch
    ContributorAuthor
    ^darken: #ff0fab, 20; ^darken: #ff00ff, 30, background-color;

    It's a bit counter intuitive TBH, but you're right, it does work.

    How about this example?

    box-shadow: 0 0 4px $alpha($darken(rgba(255, 100, 5, var(--alpha, 1)), 20), 80), 
                0 0 8px var(--color, $darken($alpha(hsla(100, 100%, 50%, var(--alpha, 1)), 80), 20));

    Not only that you need to evaluate var(--alpha), but you also need to evaluate rgba and hsla yourself. Moreover, $darken and $alpha need to be evaluated in a specific order because the value they return is used as an argument for other functions. This is fine for SCSS, which compiles everything ahead-of-time, but the parser of Assembler CSS works in real-time.

    There are two solutions (ish) to all the pre-evaluating, 1, providing the arguments like this:

    [{
    	type: 'color',
    	value: '#00BBBB',
    	raw: 'rgb(0, 187, 187)',
    }, {
    	type: 'measurement',
    	value: '16px',
    	raw: '1rem',
    }]

    and two, just providing the raw string split by commas

    ["rgb(0, 187, 187)", "1rem"] --> from the original: "background: $myFunction(rgb(0, 187, 187), 1rem)"
    

    This method would make a lot more sense from a performance standpoint, and it would also allow functions without huge performance impact. (Theoretically this would be the same as mixin performance)

    Also note that with this method variables and colors and such would be left to the function, not assembler, this could be added separately with something like AssemblerCSS.compute("rgb(0, 187, 187)") which could return a uniform style output, convert units, eval vars, etc.

    Note: The only thing Assembler would eval before passing the args to the function would be nested functions. Everything else would be passed as it appears in the css.

    This is fine for SCSS, which compiles everything ahead-of-time, but the parser of Assembler CSS works in real-time.

    TBH if the people designing their websites with assembler are super concerned about the performance impact, they could just not use the functions, right?

  4. Explosion-Scratch commented on Sep 13, 2021

    @Explosion-Scratch
    ContributorAuthor

    Looks similar to Mixins, except, we don't need to use this special char ^ in x-style for functions

    And mixins can't be nested, and if I came across this code I wouldn't know what's going on:

    ^darken: #ff00ff, 30, background-color;

    but this on the other hand:

    background-color: $darken(#ff00ff, 30);

    makes a lot more sense.

    Basically it's an issue of syntax, not necessarily performance, as the performance could be solved by just passing raw parameters to the assembler.

  5. Awilum commented on Sep 13, 2021

    @Awilum
    Contributor

    For me, Functions looks more intuitive and flexible than Mixins.

  6. locked and limited conversation to collaborators on Sep 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions