LESS: create variables in a way similar to 'nested rules' - less

Actually I have several LESS variables defined in the following way:
#toolbar-first-level-item-color-background: #transparent-black-80;
#toolbar-first-level-item-color-background_hover: #black;
#toolbar-second-level-item-color-background: lighten(#toolbar-entry-color-background,30%);
#toolbar-second-level-item-color-background_hover: lighten(#toolbar-entry-color-background_hover,30%);
#toolbar-third-level-item-color-background: lighten(#toolbar-entry-color-background,40%);
#toolbar-third-level-item-color-background_hover: lighten(#toolbar-entry-color-background_hover,40%);
#toolbar-fourth-level-item-color-background: lighten(#toolbar-entry-color-background,45%);
#toolbar-fourth-level-item-color-background_hover: lighten(#toolbar-entry-color-background_hover,45%);
As you can see, there are several repetitions in it, so I wonder if could be possible to use something like namespaces or maps to create a more compact and less repetitive declaration.
The idea is starting by structure of nested rules, that create a very clear hierarchy with few repetitions.

I think, you can use a map. It is a new feature in Less lang that allows you to get values using keys.
You can write something like that:
#toolbar: {
#first-level-item: {
color-background: #fff;
};
}
text {
color: #toolbar[#first-level-item][color-background];
}

Related

Doing this on kotlin is a bad practice?

The second way is a little smaller but i dont know if this is okay, can i use also just for be able to use expression body and put the first line of the cod on the side of method name?
override fun findOrdensColeta() {
view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
override fun findOrdensColeta() = view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
Yes, I think the second version is bad style. I see no good reasons to use also() like that, and several reasons not to:
also() is intended for use within expressions, where you don't have the option of adding a separate statement. (The classic case is logging a value before doing something with it.) That doesn't apply here, where two simple statements work just as well. So there's no benefit other than conciseness; using also() here is unnecessary complexity.
The second version has an expression body, which looks like it returns a useful value — but it actually returns the result of calling setProgressBarVisibility(), which is presumably Unit just like the first version. So the expression body is highly misleading.
Also, the only reason that the second version is shorter is that the first statement has been squeezed onto the same line. I don't think that's justified here* — it joins two things (the function signature and the call to setProgressBarVisibility()) that aren't directly related, and it makes the line too long for most people to read easily. (I'm surprised you find the second version easier to read. I tend to prefer conciseness, but even I find the first version a good deal easier to read — probably because it falls into a very familiar pattern that doesn't need any extra thought.)
If you cared only about reducing the number of lines, then the first version could be written like this (not recommended!):
override fun findOrdensColeta() { view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
(You could join even more lines, perhaps squeezing it all onto a single line if you wanted to make it completely unreadable!)
Conversely, if there were other good reasons for using the second version, it would be better if wrapped like this:
override fun findOrdensColeta()
= view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
So as you can see, the difference in length is mainly due to the (unjustified and confusing) line-joining, not the use of also().
So using also() here has no real benefit, as well as some significant drawbacks.
* I'm not saying you should never put the function body on the same line as its signature. That can work well if the body is an expression that's short enough to fit neatly all one line. For example:
override fun toString() = "MyClass(val1 = $val1)"
However, if that makes the line very long, or wraps onto further lines, or is a function body, then it's almost always more readable to start the body on the next line in the traditional fashion.
I believe the second one is a bad approach.
also is designed to provide the ability to modify or use the receiver and return it afterwards.
In your case, also is not containing any usages of its receiver (which is the result of view.setProgressBarVisibility(View.VISIBLE) ). Therefore it is not needed here
The second version is a bit confused to me - if you take the first one as the standard way to do things, a simple code block with two statements in it, what benefit does the second one really give you? You're basically using expression syntax to make it a one-liner - but it's not a one-liner, so you have to add a scope function just to give yourself back the curly braces so you can add another line of code!
So this:
override fun findOrdensColeta() {
view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
Does exactly the same thing as this:
override fun findOrdensColeta() = view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
But with the latter
it appears to return a result from setProgressBarInvisibility because it's a single-expression function (the original clearly returns nothing)
the use of also which passes that result value through reinforces the idea that you're trying to return that result
the also block implies you're using that value for something (otherwise why's it there?) and it takes a moment to see that you're not
when you realise none of the above are true, now you might be wondering if you're missing something, or if the original coder intended something specific but made a mistake
Because the basic function block is so simple and readable and a natural fit for what you're doing, doing something else can throw up some questions, or be confusing to read. Sure the way it's formatted you've saved a single line, but now it's harder to understand, y'know?
This is something to watch out for in Kotlin I think (and I'm guilty of this myself) - being able to chain stuff together sometimes encourages people to go for "one-liners" that are hard to follow, but hey at least you didn't (explicitly) create a variable! That's not what you're doing here (you're creating an unnecessary variable actually!) but it feels like a similar thing - trying to make a single expression instead of doing things the old-school way.
Coding is about trying to strike that balance between simplicity and readability, and elegant efficiency, and a lot of it's about learning what tools and tricks are available, and knowing when to use them (and how best to do it) and when to avoid them. At the end of the day it's a style choice and this is just my opinion (although all the other commenters so far are saying similar things) but hopefully it's given you something to think about! I've been there too - including using expressions for functions that don't return a value at all - but I think that's all part of learning a language and the things it offers you

How to enable selection between multiple BasicTextField in Kotlin Compose

As you can see here, there is a composable function available to use as a wrapper for Text functions:
SelectionContainer {
Column {
Text("test1")
Text("test2")
Text("test3")
}
}
However, it does not work with BasicTextField.
For more context,
I'm attempting to make the CodeViewer editable and I don't want to use a single BasicTextField as they did in Notepad for "simplicity".
I'm considering implementing something similar to SelectionContainer for my use case but I'm not sure if it's possible or even a good idea.
Any thoughts?

LESS variable concatenation and interpolation

I'm attempting to override Bootstrap's hover effect on the buttons. I'd like to save some space and do it the slick way by simply passing into a mixin the name of a class and have that class' background variable be automatically deduced from just that. So my mixin is:
.btn-hover(#name){
.#{name}:hover{
background: lighten( #~"#{name}-bg", 10% );
}
}
.btn-hover(btn-primary);
But I can't seem to access the variable #btn-primary-bg by concatenating -bg to btn-primary, because #~"#{btn-name}-bg" results in a compiler error. Is what I'm trying to do even possible? It would be pretty slick if it were.
Edit -----------------------------------------------------------------
Just stumbled upon this question and it's definitely related, but I think my question really just boils down to:
In LESS, can you access a variable via interpolation after string concatenation?
#btn-success-bg: #00ff00;
#name: btn-success;
#background: #~"#{name}-bg"; // How do I access #btn-success-bg?
You can do:
#btn-primary-bg: red;
.btn-hover(#name){
.#{name}:hover{
#buttonname: ~"#{name}-bg";
background: lighten( ##buttonname, 10% );
}
}
.btn-hover(btn-primary);
Also see: http://lesscss.org/features/#variables-feature-variable-names

Custom CSS attributes while using LESS?

I have been using SASS for a while now, and one thing I really like is how I can use it for my FlashBuilder projects also, namely that is supports custom CSS attributes, like 'embedAsCFF' and 'unicodeRange'.
I'm trying out LESS for the first time, and it will not let me compile to CSS while using these two custom attributes:
embedAsCFF: true;
unicodeRange: U+0021, U+0023-U+0026, U+0028-U+002a, U+002c, U+002e-U+0039, U+0040-U+005d, U+0061-U+007d;
I receive a 'Less Compilation Error: Syntax Error...'
Any LESS users know how I need to add in support for these custom attributes? Thanks in advance.
Update: This issue will be resolved in the release of LESS 1.4.2
Not a Custom Name but a Format Issue
It appears on my experimenting that the issue is really the fact that you are using capital letters in the property names (not that they are custom attributes themselves). Capital letters are apparently not supported by LESS. In other words, these work:
embedascff: true;
embed-as-cff: true;
unicoderange: U+0021; //etc.
unicode-range: U+0021; //etc.
But this does not:
Color: red;
I have not for certain isolated where in the actual LESS code itself this might be fixed (if it can be fixed for the way LESS handles the property rules). I suspect the cause is in the parser.js file lines 1578-1584 (as of this writing), which are:
property: function () {
var name;
if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
return name[1];
}
}
This seems to be filtering out allowing for capital letters. I don't know what the consequences would be if that regular expression was changed to allow for them.

less.css - set css parameter dynamically

I learning how to use less.css for creating dynamic css files.
I'd like to create a dynamic property in my css file and load it, for example:
#marginProperty : margin-left;
.top
{
#marginProperty: 10px;
}
Is this possible? Doesn't seem to compile for me. Any ideas?
It doesn't work quite that way; you can't set a property from a variable, variables are only values of those properties. Instead of setting a variable for the property, you should use a mixin. It's tricky, not knowing exactly how you are structuring your LESS/CSS or what your goals are, but it seems like you need to think in reverse. CSS, like SQL, is declarative, so you have to describe the result from the code, instead of describing the process of getting to that result. Something like this might do it:
.margin(#size:10px) {
margin-left: #size;
}
.top {
.margin(10px);
}
That .margin mixin can be defined in one mixin file and you can #import it, and when you need to redefine it, substitute that mixin file for another similar one.