Is there a rule to prevent empty lines at the beginning of the block? - stylelint

Is there a stylelint rule to obtain the following?
I've read the documentation but I wasn't unable to find one
/* bad */
a {
color: pink;
}
/* good */
a {
color: pink;
}

This solves my issue
"declaration-empty-line-before": ["always", {
"except": ["first-nested"],
"ignore": ["after-comment", "after-declaration"]
}],
Ref: https://stylelint.io/user-guide/rules/declaration-empty-line-before/#first-nested

Related

Stylelint: нow to sort properties before nested classes

I can't find a rule that would automatically fix this:
.a {
.b {
width: 16px;
}
padding: 2px 0;
}
on this:
.a {
padding: 2px 0;
.b {
width: 16px;
}
}
You can use the order rule of the stylelint-order plugin to order things inside of rule sets.
To ensure nested rules come before declarations you should add the following to your Stylelint configuration:
{
"plugins": [
"stylelint-order",
],
"rules": {
"order/order": [
["custom-properties", "declarations", "rules", "at-rules"]
]
}
}

VSCode/TextMate syntax highlighting grammar -- matching code until end of line

I am writing a TextMate grammar to implement syntax highlighting in VSCode for a custom flavor of Markdown. I would like everything on the same line after ##$ to be highlighted as Javascript.
This is what I came up with:
"majsdown_execute_statement": {
"begin": "(.*?)(##\\$)",
"name": "test",
"end": "(\\r\\n|\\r|\\n)",
"beginCaptures": {
"2": {
"name": "keyword.control.majsdown"
}
},
"patterns": [
{
"include": "source.js"
}
]
},
That almost works:
But I would like the ##$ part to always be highlighted as a keyword. Here's a mockup (edited image) of my desired result:
I've tried a lot of different combinations of "begin" and "end", and I've also tried many nested patterns like the following one:
"patterns": [
{
"begin": "\\s",
"while": "^(\\r\\n|\\r|\\n)",
"patterns": [
{
"include": "source.js"
}
]
}
]
Unfortunately, nothing provides the result I desire. How can I achieve my desired result?
To handle multiline constructs, I think you'll have to provide modified embedded language(JavaScript) definition as well. Easiest way to do it would be to make ##$ a comment in JavaScript, so it'll not mess up existing constructs.
I have no idea about VScode syntax highlighting. I'll try to demonstrate the idea using HighlightJs. It has very similar way of defining a language.
Demo: View in full page mode.
hljs.debugMode();
// default code for the demo
src.innerText = `
My custom markdown highlighted with custom rules.
Here is how javascript code looks:
##$ function test()
##$ {
##$ // TODO: stuff
##$ let rand = Math
##$ .random()
##$ .toFixed(2);
##$ }
##$ var string = "hello";
##$ const string2 = \`some long
##$ string\`;
Leave one empty line to get out of the code block.
Here is some more code:
##$ var rand = Math.random();
##$ console.log(rand);
We are out of the second code block now.
`;
// define our markup language, say 'mdown'
let langDef = {
name: 'Mdown',
aliases: ['mdown'],
case_insensitive: true,
contains: [
{
className: 'mscript',
begin: /##/,
end: /\$/,
keywords: { name: 'mscript' },
contains: [],
starts: {
end: /^\s*$/, // end on empty line
returnEnd: true,
subLanguage: ['js'], //embedded language
},
},
],
};
hljs.registerLanguage('mscript', () => langDef);
// patch javascript multiline structures
let js = hljs.getLanguage('javascript');
for (let c of js.contains) {
if (c.begin === "`") { // handle templet literals
c.contains.unshift({
begin: /^##/,
"relevance": 0,
end: /\$/,
contains: [],
scope: 'mscripttag'
})
}
}
// console.log(js);
// make '##$' a comment :)
// So it'll not mess existing styling
js.contains.push(hljs.COMMENT(/##/, /\$/, { scope: 'mscripttag', relevance: 10 }));
// for demo update highlighted code on user input
let handleChange = (event) => {
let html = hljs.highlight(src.innerText, { language: 'mscript', ignoreIllegals: true }).value;
code.innerHTML = html;
};
// javascript patching done
document.addEventListener('DOMContentLoaded', handleChange);
src.addEventListener('input', handleChange);
body { font-size: .8rem; }
.input {
width: 46%;
background-color: #eee;
display: inline-block;
overflow: auto;
}
.output {
width: 50%;
display: block;
float: right;
background-color: #ccc;
}
/* add extra theme for our tag ##$ */
.hljs { color: #bbb !important; }
.hljs-mscript,
.hljs-mscripttag { color: red; }
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/base16/snazzy.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/highlight.min.js"></script>
<div>Edit below markdown code.</div>
<pre class="input"><div id="src" contenteditable></div></pre>
<pre class="output"><code id="code" class="javascript hljs">abcd</code></pre>
In case the library not available, here is how the output looks like:
In above code I have defined ##$ <jscontent> \n as a tag in our markdown language definition. And the content will be processed according to the embedded language JavaScript. Next I've modified the default JS language definition and added ##$ as a comment so it'll be harmless to exiting syntax. Now we just need to handle template literals which are multiline. In the literal definition I've added ##$ as a part of the literal, but with different scope/name/styleOption msscripttag.
I hope you'll be able to define similar syntax in TextMate for VSCode.
try using match instead...
"patterns": [
{
"name": "keyword.control.factory",
"match": "(\\w|-)[^(]*"
}
]
this code matches everything up to a "(" character
so your code look something like this:
"majsdown_execute_statement": {
"patterns": [
{
"name": "keyword.control.majsdown",
"match": "(?<=##\$)\\w*"
}
]
}
you can also try [^##$]*(\\w)
try it out here

How to enable type annotations in VS Code for a single variable

As I understood correctly VS Code already has support for type annotations in TypeScript and JavaScript, but how do I enable it or use it properly for inline variables where VS Code does not understand the referer correctly?
Here is my code:
export const TooltipModule = {
init() {
this.tooltipElements = document.getElementsByClassName('tooltip')
if (this.tooltipElements.length > 0) {
this.enableTooltips()
}
},
enableTooltips() {
/** #var {Element} tp */
for (const tp of this.tooltipElements) {
new Tooltip(tp /* no type annotation here */, {
placement: 'bottom',
title: 'Top',
})
}
},
}
I have also tried using #type or #param.

Make default Ionic alerts larger

I'm trying to make the default Ionic Alerts larger. I'm developing an app that needs to have easy touch points and the default alerts are too small for what I'm needing.
I've tried enlarging the font as well as expanding the width of the alerts but nothing seems to actually make the alerts larger.
Any easy/best ways to do this?
AlertController supports custom classes which could be placed in your component's scss file and there you can do necessary alterations.
For example in your component's ts file you can have this method that creates alert with reference to custom class "scaledAlert":
delete() {
let confirm = this.alertCtrl.create({
title: "Are You Sure?",
cssClass: "scaledAlert",
message: "this will remove image from your image gallery",
buttons: [
{
text: "Cancel",
handler: () => {
console.log("Canceled delete");
}
},
{
text: "Confirm",
handler: () => {
console.log("deleting...");
this.deleteImageFromGallery(this.image)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
this.viewCtrl.dismiss();
}
}
]
});
confirm.present();
}
Now in the scss file you add class to style as you need to scale the controller, such class goes after your page or component:
home-page {
.item {
min-height: 2rem; /* <- this can be whatever you need */
}
ion-label {
margin: 0px 0px 0px 0;
}
.item-content {
padding-top: 0px;
padding-bottom: 0px;
margin-top: -12px;
margin-bottom: -12px;
height: 50px;
}
}
.scaledAlert {
transform: scale(1.5);
}
Here I used just naive "scale" function which may require you to add some cross browser compatible versions of it. But you should achieve what you want with it (it worked in my app without issues).
Alternatively you can override default styles using saas variables: https://ionicframework.com/docs/api/components/alert/AlertController/#sass-variables
You will have to alter them in theme\variables.scss" which is located in your project's folder
See more here: https://ionicframework.com/docs/theming/overriding-ionic-variables/
And third option is indeed to check elements' style via devtool and attempt to override those classes. But I don't like that way, feels a bit more hacky.
Some of the styles for alert are not getting updated if written in component SCSS file. The styles need to be written in the global scss file.

Conditional statements with SCSS

Does anyone know if this is possible:
I want my brand colour to be $brand: #00cccc;
however, I want to change that on just one page, and that page is defined by a class on it's body.
body class="purple"
Now my mind is thinking that this would be ideal:
body.$class {
#if $class == 'purple'
{
$brand = #ff0033;
}
#else
{
$brand = #00cccc;
}
}
But that's not correct syntax at all.
Is this something that can be done in a similar way?
I believe you are looking for something like this?
#each $class in purple, none {
$brand: #00cccc;
$selector: 'body';
#if $class == purple {
$brand: #ff0033;
$selector: 'body.' + $class;
}
#{$selector}{
/* Use $brand */
}
}
I don't believe there is an #if statement you could create for that. In LESS you could redeclare the same variable inside body.purple and it would only apply inside that block, but in Sass/Scss redeclaring the variable will change it globally. This might not be ideal but you could redeclare the variable twice, once at the top for the purple color, and once at the bottom to set it back to its default value.
scss
// Global Variables
$blue: #0cc;
$purple: #f03;
$brand: $blue;
body {
color: $brand; // blue
}
.purple {
$brand: $purple;
color: $brand; // now purple
// all other styles
$brand: $blue;
}
.test {
color: $brand; // back to blue
}
css output
body {
color: #00cccc;
}
.purple {
color: #ff0033;
}
.test {
color: #00cccc;
}
Here is an article about the variable scope differences between LESS and Sass. http://blog.freeside.co/post/41774744757/less-vs-sass-variable-scopes
Yes, as of 2022 Sass does include #if and #else rules for flow control. More info on the Sass documentation site.
The #if rule is written #if { ... }, and it controls whether or not its block gets evaluated (including emitting any styles as CSS). The expression usually returns either true or false—if the expression returns true, the block is evaluated, and if the expression returns false it’s not.
For example, this Sass code:
$light-background: #f2ece4;
$light-text: #036;
$dark-background: #6b717f;
$dark-text: #d2e1dd;
#mixin theme-colors($light-theme: true) {
#if $light-theme {
background-color: $light-background;
color: $light-text;
} #else {
background-color: $dark-background;
color: $dark-text;
}
}
.banner {
#include theme-colors($light-theme: true);
body.dark & {
#include theme-colors($light-theme: false);
}
}
...will produce this CSS:
.banner {
background-color: #f2ece4;
color: #036;
}
body.dark .banner {
background-color: #6b717f;
color: #d2e1dd;
}
There is also support for #else if and Boolean operators and, or, and not.