Less Class Name String Interpolation Not Working

LESS class name string interpolation not working

Escaped selector interpolation is deprecated in 1.4.x, use

.col@{index} {
width: @baseWidth * @index;
}

instead.

How to fix string interpolation is not working in textarea with fornControlName?(Angular)

The issue is, that [formControlName] expects string name of the given form control. And you are passing reference to it. If you form group workSampleEditForm contains work_sample_description form control then just pass its name as a string (put the name in the single quotes)

<textarea 
matInput rows="7"
[formControlName]="'work_sample_description'">
</textarea>

As mentioned by @MikeOne, if you get the value of this.WorkSampleObj.work_sample_description from API and not when the Form is created, you should set it using setValue.

ngOnInit(): void {
this.someApiCall.subscribe((res) => {
this.testForm.get('textAreaFC').setValue(res.value);
});
}

See updated stackblitz.

Why can I not use string interpolation for classNames in React?

One problem is that classes is an array of strings, not an object, so spreading it into a template literal doesn't make sense. Join by whitespace instead:

<button className={`button ${classes.join(' ')}`}>

Spread can only be used in:

  • argument lists: fn(...args)
  • array literals: [...items]
  • object literals: { ...props }

But it can't be used wherever a generic expression is expected.

LESS mixin a variable class name

There are at least 2 problems with what you are trying to do (for LESS >=1.6 see update bellow):

1) Unfortunately it is not possible to call a mixin using selector
interpolation.

With selector interpolation LESS expects the construct to be of
following format:

.@{selector-string} { property:value; }

(the interpolated selector can have also some static string pre or
post the interpolation)

so

.@{selector-string};

is Unrecognised by the LESS compiler. See more here:
How can I call a mixin by reference in LESS?

2) A ruleset with an interpolated selector gets directly printed to the CSS output and does not exist as a mixin that you could reuse in the LESS run

For example:

@foo: test;

.@{foo} {
length: 20px;
}

.bar {
.test;
}

will return:

    Name error: .test is undefined
.bar { .test;}

See more on that here: LESS CSS: Reuse generated .@{name} class as a mixin

Possible solution for your problem would be redifinig the font awesome rules as some kind of reusable mixins (without using interpolation). Something like this:

@fa-var-github: "\f09b";

.fa-mixin() {
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fa-mixin-lg() {
font-size: (4em / 3);
line-height: (3em / 4);
vertical-align: -15%;
}
.fa-mixin-icon(@icon){
@var: "fa-var-@{icon}";
&:before { content: @@var; }
}
i {
.fa-mixin;
.fa-mixin-lg;
.fa-mixin-icon(github);
}

If you don't really need the variables and just want to include the rules, the best way would be just to import the compiled CSS version of the FontAwesome (see answer here):

@import (less) 'font-awesome.css';

and then you can just use the CSS rules like LESS mixins or extend their selectors as you see fit and it should work perfectly.


Update:

As of LESS >= 1.6 rules with interpolated selectors can be accessed as mixins ... so the #2 limitation form above does not apply anymore (but you still can not call a mixin dynamically with interpolation). So you can simply call LESS mixins and variables from the imported font-awesome.less file like so:

i {
.fa;
.fa-lg;
&:before{
content: @fa-var-github;
}
}

LESS nested interpolation

Note: The alternate approach used in your answer looks more cleaner and better to me. It could possibly be improved further but that's beyond the scope of this answer. I am posting this answer only to show what was wrong with the code in question.

As I had mentioned in my comment, the standard syntax for selector or property interpolation is @{}. Only when this syntax is encountered the compiler realizes that it must evaluate a variable with same name and substitute its value. For the following statement:

@background: ~'@@{theme-name}-background';

the below are the steps that the compiler would perform:

  • As soon as it encounters @{theme-name}, it knows that the value of the variable should be put in there and so replaces it with pastel or antique or hipster.
  • Now we can assume the compiler to see the above statement as ~'@pastel-background'. Since there are no further {} wrappers, the compiler sees it as just another string and leaves it as-is.

If there was another wrapper (like ~'@{pastel-background}'), the compiler will see it as yet another variable which has to be evaluated, look for a variable named pastel-background and use its value.

@all-themes: pastel, antique, hipster;

@pastel-background: #a7b3a5;
@pastel-primary: #b4bdc0;

@antique-background: #856357;
@antique-primary: #eae3ea;

@hipster-background: #1a2930;
@hipster-primary: #f7ce3e;

.generate-themes(@i:1) when (@i <= length(@all-themes)) {
@theme-name: extract(@all-themes, @i);
@background: ~'@{@{theme-name}-background}';
@primary: ~'@{@{theme-name}-primary}';

body.theme-@{theme-name} {
background-color: @background;
color: @primary;
}

// ... more definitions ...

.generate-themes(@i + 1);
}

// call the mixin
.generate-themes();

Concatenate String for class name in LESS

What you are looking for is called selector interpolation ... you can find it here: http://lesscss.org/#-selector-interpolation

Your mixin would need to look like this for it to work:

.myPL( @val ) {
.pL@{val} {
padding-left: @val;
}
}

How can I interpolate JSX with an expression in a string?

Try this (ES5):

<div className={'total total-' + obj.state}>...</div>

Or with ES6+

<div className={`total total-${obj.state}`}>...</div>

Remember that everything between { and } is just Javascript, so the expression is 'total total-' + obj.state which is then set as the class of the DOM node.

LESS generate comma separated class names

.Less has recently added @extend functionality.
Try this:

:extend(.class-name)


Related Topics



Leave a reply



Submit