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

Mixin Interpolation #1196

Closed
tomjn opened this issue Feb 21, 2013 · 13 comments
Closed

Mixin Interpolation #1196

tomjn opened this issue Feb 21, 2013 · 13 comments

Comments

@tomjn
Copy link

tomjn commented Feb 21, 2013

We have selector interpolation, yet mixin interpolation does not work

For example:

.device-type(@namespace:~'') {
    .@{namespace}-test { width:50%; }
}

.device-type(~"laptop-");

Would generate a css class laptop-test, that could be used here:

<div id="test" class="laptop-test"> .... </div>

However, if I add this, things fail:

#test {
    .laptop-test;
}

One would expect it to generate:

.laptop-test {
    width:50%;
}
.testdiv {
    width:50%;
}
@lukeapage
Copy link
Member

if "laptop-" is unknown and has to be in a variable, how come the caller knows the mixin exists?

@tomjn
Copy link
Author

tomjn commented Feb 22, 2013

I could ask that of any unknown mixin, but SASS manages it fine.

I'd imagine a crude way of doing it is to reprocess the processed code if there are any mixins, or to add generated css rules to the list of things that can be included and it can go back and fill in any blanks. Even if you couldn't define parameters and they were non-parametric, the ability to do this and use this would be handy, and it makes sense intuitively that you'd be able to use mixins that were constructed via string interpolation after they've been created.

@tomjn
Copy link
Author

tomjn commented Feb 22, 2013

I requested this because I created a port of csswizardry-grids from SASS to LESS here:

https://github.com/Tarendai/csswizardry-grids.less

But right now you can't use the classes in your LESS code, only in the html markup, else compiles fail

@lukeapage
Copy link
Member

I see...

It would be nice to at least make it work for these cases.. e.g. classes returned from mixins, where the interpolation has already occurred

@tomjn
Copy link
Author

tomjn commented Feb 22, 2013

There are 2 levels really of it, there's full mixins with args, but then there's also just treating them as generated CSS rules to be included without args

@tomjn
Copy link
Author

tomjn commented Feb 22, 2013

How much work would this be and what would be the 'method' of implementing it?

@lukeapage
Copy link
Member

an interpolated selector ends up being eval'd here

https://github.com/cloudhead/less.js/blob/master/lib/less/tree/selector.js#L29

the trouble is that it then isn't getting a positive match here

https://github.com/cloudhead/less.js/blob/master/lib/less/tree/selector.js#L8

(not sure why? - guess it could be something else stopping it, but I think that is it - I can see the following failing

@{a}-b {
}

as it will translate into 2 elements, where as

.a-b();

is a single element.. but it doesn't work even if you have

@a:~".a";
@{a}

maybe because it compares values and the value in the interpolated mixin selector is quoted ?

I am not sure how I would fix that.. you could add a falback that if it fails on element lookup it just does toCSS on both and compares that - it isn't very performant though - maybe selectors should cache the toCSS if they don't already.

So anyway, I think the above is the main problem.

A sub problem is that if you define interpolated selectors in the same scope as the mixin call, I think the mixin call is evaluated before the selector is eval'd - but thats what I meant when I said you could fix it for mixin calls or imports defining selectors using interpolation as long as it wasn't within the same scope. I'm not sure if we could fix that.

If you'd like to have a go at fixing it then please submit a pull request and if you find anything you aren't sure about just discuss it first.

We are working on extends and once that is finished, it should match interpolated selectors too.

@glasserc
Copy link

It would also be nice to be able to invoke an interpolated mixin, as in #1338.

.mixin1 {
  width: 100%;
}

.mixin2 {
  background-color: red;
}
@useMixin: 1;

.some-element {
  .mixin@{useMixin}();
}

@matthew-dean
Copy link
Member

+1 to variable use in mixin definition and call

@pauldijou
Copy link

Big +1 for both mixin interpolation and interpolated mixin!

@seven-phases-max
Copy link
Member

I will close this since it is supported now (Less 1.6.x, by #1624). And more advanced "interpolated mixin" examples/use-cases/issues to be fixed/improved are in #1399.

Btw. the example in the first post has a typo (duplicated -) so here's corrected example (I also removed redudand ~""):

.device-type(@namespace: ~'') {
    .@{namespace}test {width: 50%;}
}

.device-type(laptop-);

#test {
    .laptop-test;
}

@mhawk0
Copy link

mhawk0 commented Apr 13, 2015

I am afraid that calling a mixin with interpolated variable, e.g.

.mixin@{useMixin}();

is still not supported yet?

@seven-phases-max
Copy link
Member

is still not supported yet?

No. Neither in interpolated nor in simple variable form. (I re-opened #1338).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants