Does Less have support for Custom Elements? - less

Does Less have any support for the Web Components Custom Elements spec? (http://w3c.github.io/webcomponents/spec/custom/ or more accessible http://www.x-tags.org/docs)

Less does not put any restrictions on used selectors/properties/values as long as they meet the base CSS grammar, e.g. the following Less code:
whatever {
whatever-else: I dont care;
&:tlhIngan(Hol)[DaH="mojaq-mey-vam"] {
color: pitch black #2;
}
}
results in this CSS:
whatever {
whatever-else: I dont care;
}
whatever:tlhIngan(Hol)[DaH="mojaq-mey-vam"] {
color: pitch black #2;
}
Additionally there's special escaping syntax to pass just any characters through (i.e. ~"whatever-'characters'-here//**\#\$^%\n").
So to answer the question: Yes, Less supports custom elements as well as any future standard elements unless they introduce a new incompatible syntax.

Related

What does getHandlerId() do and how to use it?

Some of the react-dnd examples use a getHandlerId() method.
For example in the simple example of a sortable list, the Card.tsx function:
Collects a handlerId from the monitor object within the useDrop method
collect(monitor) {
return {
handlerId: monitor.getHandlerId(),
}
},
Returns that as an element of the "collected props"
const [{ handlerId }, drop] = useDrop<
Uses it to initialize an HTML attribute named data-handler-id
<div ref={ref} style={{ ...style, opacity }} data-handler-id={handlerId}>
What is this Id and why is it used?
What uses the data-handler-id attribute?
I'd expect to see getHandlerId() described in the API documentation as a method of the DropTargetMonitor (but it isn't).
I didn't dive deep into it but for me this information was enough to continue using it:
If you remove this data-handler-id, everything continue working but with some issues (item sometimes flickers, it doesn't go to another place as smoothly as it does with data-handler-id)
Here is an open issue https://github.com/react-dnd/react-dnd/issues/2621 about low performance, and this comment suggests to use handler id: https://github.com/react-dnd/react-dnd/issues/2621#issuecomment-847316022
As you can see in code https://github.com/react-dnd/react-dnd/search?q=handlerId&type=code, handler id is using for proper definition of drop item so it seems better to use it even if you don't have a lot of elements.

Get Formatter for a Language

I want to make a relatively simple formatter in VS Code. Essentially, I have a bunch of *.md.j2 files (Jinja2 templates that ultimately become Markdown). I have the Better Jinja extension to render these, with the language jinja-md in VS Code.
I started off just wanting to use prettier's Markdown formatting and call it a day. I tried adding this to settings.json:
"[jinja-md]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
},
This does not work because esbenp.prettier-vscode does not register itself for the jinja-md type; it seems to have no "break glass" option to configure that.
This got me to thinking that it would be nice to make a formatter that ignored Jinja tag lines (e.g. {% if foo == 'bar' %}\n and then passed on the fragments to whatever the underlying file type formatter was. So basically I want to do something like:
vscode.languages.registerDocumentFormattingEditProvider('jinja-md', {
provideDocumentFormattingEdits(document: vscode.TextDocument): vscode.TextEdit[] {
// THIS IS THE QUESTION:
// vscode.languages.getFormatter is not a real method. I want to know
// how to pull off this concept.
mdFormatter = vscode.languages.getFormatter('md');
// Get segments between %}\n and \n{% and route them to the
// `mdFormatter` -- I think I know how to do this and am not bothering
// to write the code here.
}
});
Is this a thing I can do -- can I programmatically get from VSCode "the formatter user-configured for language X"?

Less: how to grab an entire ruleset from within a map

I have a nested ruleset (map) like the one below.
#typography: {
#h1: {
font: roboto;
font-weight: 300;
font-size: 9.6rem;
line-height: 9.6rem;
text-transform:none;
}
}
I know how to retrieve and output a single key such as [font], but is there any way of returning and outputting the whole of inner ruleset?
.myclass {
font: roboto;
font-weight: 300;
font-size: 9.6rem;
line-height: 9.6rem;
text-transform:none;
}
"Can't work this way currently (v3.9)".
I'm afraid it's not going to work the way (specifically the map itself) it is.
Intuitively it would be something like:
#usage {
#typography[#h1]();
}
But currently this feature (cascading () and [] operators) is not implemented.
A first-guess workaround like "assign a ruleset of interest to a temporary variable and then 'call' it" also fails:
#usage {
#temp: #typography[#h1];
#temp(); // error: not callable value
}
(This one actually to be counted as a bug - I created a dedicated ticket).
This all brings us to the next section:
"Consider using mixin-based maps".
Notice that while "variable-based maps" (aka DRs) seem to be a more wide-spread pattern by now, there are five different methods to define a map in Less (and infinite number of these methods permutations to define an N-dimensional (aka "nested") map).
Each method has its pros and cons, and so far it's not clear which one to be chosen as the "go-to" one (in a long run there's tendency to unify them as tidy as possible but so far it's far from that).
Now look at the structure you're trying to represent w/o sticking to "variable -> #variable" stereotype. Does not it look like a regular CSS ruleset:
.typography {
.h1 {
font: roboto;
font-weight: 300;
font-size: 9.6rem;
line-height: 9.6rem;
text-transform: none;
}
}
?
And this way you've already got a "mixin-based map" you can use pretty much the same way you'd use a "variable-based map". (Actually the current documentation for "Maps" also suggest both methods w/o enforcing either one as "the primary").
The only modification you'll need for this "CSS" structure is to make its inner or outer (or both) rulesets to be a parameteric mixin (by adding ()) so that the rules won't appear in the compiled CSS by default.
E.g. like this:
.typography {
.h1() {
...
Or like this:
.typography() {
.h1 {
...
(Also if you prefer for these identifiers you can use # instead of .).
Now getting back to your use-case (The Solution):
.typography {
.h1() {
font: roboto;
font-weight: 300;
font-size: 9.6rem;
line-height: 9.6rem;
text-transform: none;
}
}
#usage-1 {
// "expand" the set of rules:
.typography.h1(); // OK
}
#usage-2 {
// use individual value from the map:
r: .typography.h1[font]; // OK
}
#usage-3 {
// iterate through:
each(.typography.h1(), <...>); // OK
}
// etc.
Not a surprise counting that expanding a set of rules is what the mixins were invented for in the first place.
The only fundamental difference (beside current limitations/issues on how they can be used) between "variable-based" and "mixin-based" maps to keep in mind is that "variables (and properties) override" and "rulesets (and thus mixins) cascade". This may affect some particular details when you'll need your CSS data to be customized/modified by "external code" (e.g. as in "theming/subtheming" etc.) - but that's another big story so I won't get into it here, although see the next section for some tips.
"Mixins and variables interop".
And one more important thing to understand about mixins (in context of the use-case).
If we'll think of variables as an abstract programming thing, i.e. "an identifier (symbolic name) associated with a value" we quickly see that a mixin is just that: a variable.
A "mixin" (its name) is really nothing but an identifier to refer to a value, i.e. -> variable.
It's just the identifier characters (# or . in front) plus a limitation on what kind of values it can hold is what makes it to be referred to by a different title, i.e. "mixin" instead of a "variable" (as in "Less #variable").
In other words, when it comes to "I have some data and I need something (i.e. "a variable") to hold/represent it", it's important to not automatically fall into the "a variable (in a generic sense) -> #variable" trap.
So getting back to the Q, another trick to have in mind is to know that mixin and variable values (specifically if it's a "ruleset" value) can be (almost) freely assigned/reassigned to each other. I.e. basically, you can create a variable to refer to a mixin-based map and create a mixin to refer to a variable-based map.
This may be valuable to overcome current issues/limitations (mostly in usage) of both methods (or if you just prefer more of #, . or # "code-look" where maps are used).
Here're a few tips:
// ................
// "Universal" map:
.typography {
.h1() {
font: roboto;
font-weight: 300;
font-size: 9.6rem;
line-height: 9.6rem;
text-transform: none;
}
#h1: {.typography.h1}; // assign mixin to variable
.h2() {#h1()} // assign variable to mixin
.h3() {.typography.h1} // assign mixin to mixin
#h2: #h1; // assign variable to variable
}
#typography: {.typography}; // assign mixin to variable
.graphytypo {.typography} // assign mixin to mixin
// etc.
// ................
// Usage:
#usage-1 {
// use individual values from the map (all roboto):
1: .typography.h1[font];
2: .typography[#h1][font];
3: .typography.h2[font];
4: .typography.h3[font];
5: .typography[#h2][font];
6: #typography[#h1][font]; // <- like your original map
7: .graphytypo.h3[font];
// etc.
}
#usage-2 {
// expand a set of .h1 rules (all the same):
.typography.h1();
.typography.h2();
.graphytypo.h3();
// etc.
}

Is it possible to un-nest (or re-nest) a selector block in LESS?

Say I have some LESS styling like:
.some-context {
.some-parent {
.some-nav {
a {
color: blue;
&.active { color: black; text-decoration: underline; }
}
}
}
}
Basically, we were styling links within one particular deep context in a certain way.
But now we have a second context that needs the same link styling.
I know I can use & to repeat the parent selector, but is there a way to "unset" the parent selector? Instead of re-using/re-arraging the parent selector, I want to discard it.
(I have used &:extend() to "steal" styling of other parts of the page from another context, but ends up quite fragile — quietly breaking whenever the other code/nesting ever changes. So I'm looking for alternatives.)
Is there a way to do something like:
// (deep within a nested context)
a, ⅋ .other-context a {
// …
}
…where whatever actual syntax "⅋" is standing in for would mean "reset the context and discard all parent selectors"?
Unfortunately, it is not currently possible (as of December 2018), but there is an open github feature request that can be found here. However, if you consider the option of switching to SASS, then you could use its #at-root directive.

LESS CSS: selector substitution?

This is an existing general css rule (original file):
.caption-top {
color: red;
}
This is schematic, because in real life case, I need the .caption-top selector to become something else, depending on the context. But I would like to use a variable instead of changing the all occurrences of the selector. For example, in one context, it should become .field-name-field-caption-top. So I did this (wrapper file):
#caption-top: .field-name-field-caption-top;
#caption-top {
color: red;
}
This generates a LESS parse error. Is there another method to establish a rule to substitute a selector? So that, for the above example, the rule will finally look like this:
.field-name-field-caption-top {
color: red;
}
Additional info
The whole point is to not touch the original css file, because it comes from outside and will be overwritten, but instead, to wrap it and tell Less how to replace existing classes with classes used in a particular theme. If it is not possible to achieve, then acceptable solution will be to change the original file in an automatic way, like e.g. replace all occurrences of ".caption" with "#caption" (which I suggested in the above code sample) or make an import at the beginning etc. Then use a wrapper Less file (aware of the theme implementation) to specify what classes whould be replaced with what.
You can use escaping to achieve this:
#selector: '.myclass';
(~'#{selector}') {
color: red;
}
However you cannot do this:
(~'#{selector}') .another {
color: red;
}
To achieve the above you will need to alter the variable
#selector: '.myclass .another';
You need to produce a function of two arguments that generates the desired CSS:
.generator(#fieldName, #fieldCaption) {
.#{fieldName}-#{fieldCaption}-top {
color: red;
}
}
.generator(foo, bar);
(Feel free to try this in the online less compiler)
This piece of code produces the desired CSS for elements with name "foo" and caption "bar". You just need to make more calls to the .generator function with different arguments to obtain what you need.
If this does not correspond to what you need, please provide one additional example of your desired CSS output.
It looks like mixins are what you need:
.caption-top {
color: red;
}
.field-name-field-caption-top {
.caption-top
}
You can define a class that, used or not, you can then reference again and again inside other selectors. You can even combine them with new styles, thereby extending what the original block of CSS would have done:
.field-name-field-caption-bottom {
font-size: 3em;
.caption-top
}
Give it a go in the compiler!