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

difference between a imported namespace and a declared one #1895

Open
bassjobsen opened this issue Feb 23, 2014 · 14 comments
Open

difference between a imported namespace and a declared one #1895

bassjobsen opened this issue Feb 23, 2014 · 14 comments

Comments

@bassjobsen
Copy link
Contributor

this code work well:

#ns {
.nsmixin(@color){
color: @color;
}
}

.mixin()
{
.test2 {
        #ns > .nsmixin(blue);
}
}
.mixin();

Then i create a file ns.less which contains:

.nsmixin(@color){
color: @color;
}

now the code below shows an error:

#ns { @import "ns.less";}

.mixin()
{
.test2 {
        #ns > .nsmixin(blue);
}
}
.mixin()

error: "SyntaxError: #ns > .nsmixin is undefined" this only happens when its wrapped inside a mixin. Use the namespace in a class works well too:

   #ns { @import "ns.less";}
   .test2 {
        #ns > .nsmixin(blue);
    }
@lukeapage
Copy link
Member

The problem is we process mixin calls before we process rulesets - so that mixins can bring variables into scope.
Although we process imports before mixin calls, we don't do that recursively.

To fix this we need to pull out the import process to a seperate visitor before the eval call. I think this would be a good idea.

work-around would be to wrap everything in & e.g.

#ns { @import "ns.less";}
& {
    #ns > .nsmixin(blue);
}

@bassjobsen
Copy link
Contributor Author

Thank for your quick response. I agrees it seems a good idea to fix this.

NB i don't understand how if have to wrap my namespace mixin in:

.mixin()
{
.test2 & {
    #ns > .nsmixin(blue);
}
}
.mixin();

@lukeapage
Copy link
Member

NB i don't understand how if have to wrap my namespace mixin in:

Sorry.. what do you mean?

@CMCDragonkai
Copy link

I've been looking for something like this.

I would like to namespace external third party code while also "referencing" them. This makes CSS closer to modular architecture similar to CommonJS.

Something like this:

@import (reference) "../../components/bootstrap/dist/css/bootstrap-theme.css" as #Namespace;

This makes all the CSS code inside bootstrap-theme contained inside the #Namespace, while still abiding by the (reference) keyword.

A question, can variables be "namespaced"? They seem like they can't.

#Namespace{
    @variable: 4px;
}
#Namespace@variable;

@bassjobsen
Copy link
Contributor Author

@lukeapage i try to find a fix for:

  #ns { @import "ns.less";}

 .mixin()
 {
 .test2 {
  #ns > .nsmixin(blue);
 }
 }
 .mixin();

@CMCDragonkai see #1848 for namespaced vars. to wrap a third party less file use #bootstrap {@import "../../components/bootstrap/dist/css/bootstrap-theme.css";}

update (for @CMCDragonkai) #bootstrap {@import (reference) "bootstrap.less";} compiled indeed all bootstrap's code into the CSS. Maybe this should be an other question. I'm not sure what to expect when referencing a namespace.

@seven-phases-max
Copy link
Member

@bassjobsen

#ns {@import "ns.less";}

.mixin() {
    .test2 {
        #ns > .nsmixin(blue);
    }
}

& {
    .mixin();
}

I.e. the problem there is not that .nsmixin is not visible inside .mixin itself but that it's invisible in the global scope (the scope where #ns is defined).
Alternatively it can be solved via:

.-;.-() {#ns {@import "ns.less";}}

.mixin() {
    .test2 {
        #ns > .nsmixin(blue);
    }
}

.mixin();

@CMCDragonkai
Copy link

@bassjobsen What do you mean? Neither this syntax

#bootstrap {@import "../../components/bootstrap/dist/css/bootstrap-theme.css"}

Nor what I suggested

@import (reference) "../../components/bootstrap/dist/css/bootstrap-theme.css" as #Namespace;

Currently works? I get a syntax error.

@seven-phases-max
Copy link
Member

@CMCDragonkai #bootstrap {@import (less) "..../bootstrap.css";} and #bootstrap {@import (less, reference) "..../bootstrap.css";} work since Less 1.5.0 (don't miss ; in the end of the import statement). See the docs.
Namespacing "bootstrap.less" is not recommended since it does not work properly that way, see #1826, #1709 etc.

@bassjobsen
Copy link
Contributor Author

@seven-phases-max, thanks that (the & for my mixin) works well

@CMCDragonkai
Copy link

Hey @seven-phases-max

I used your snippet. And it works some what. There's an issue.

So this does not work (I get the undefined error):

#bootstrap {@import (reference) "..../bootstrap-theme.css";}
.class{
    #bootstrap.input-sm();
}

However this does work:

#bootstrap {@import (less) "..../bootstrap-theme.css";}
.class{
    #bootstrap.input-sm();
}

It seems that this importing external files into namespaces only works when the original code is considered to be a "less" file.

However the file that I'm importing is just a CSS file. Furthermore I want to "(reference)" it. So is there a way to make less recognise that I want to reference it and process it as a less file?

@seven-phases-max
Copy link
Member

@CMCDragonkai I've updated my answer with correct imports. Later on please use the SO for a general "usage/how-to" like stuff. It's quite difficult to track the issues in time when discussion there quickly spreads too wide.

@CMCDragonkai
Copy link

@seven-phases-max Sorry for derailing the discussion. But @bassjobsen brought up an issue while doing it your way:

update (for @CMCDragonkai) #bootstrap {@import (reference) "bootstrap.less";} compiled indeed all bootstrap's code into the CSS. Maybe this should be an other question. I'm not sure what to expect when referencing a namespace.

I used your updated snippet. And yes it does work now, but "reference" does not actually reference properly, the entire CSS code in Bootstrap is imported into the output.

This indeed can be a separate question.

@seven-phases-max
Copy link
Member

@CMCDragonkai OK, then I guess that's a good case for another ticket, i.e. @import (less, reference) "bootstrap.less"; works as expected but #bs {@import (less, reference) "bootstrap.less";} does not.

@CMCDragonkai
Copy link

#1896

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

4 participants