Creating classes programmatically with Stylus - stylus

I wonder if there's a way to programmatically create classes with stylus using Iterators.
Example:
$my-colors = {
"black": #344F5E,
"grey": #E0E0E3,
}
I know there's define() but I'm not sure if that works and if so how I would access the key and the value side.
like
for col in $rf-colors
define('rf-bg-' + col #() {
background-color:
})
Goal is to extend the color pallette and have all classes automatically generated. Maybe I'm using the completely wrong approach.

You can use interpolation with {} and a loop on a hash for $key, $value in $hash:
$my-colors = {
"black": #000,
"white": #fff
}
for $name, $color in $my-colors {
.{$name} {
background-color: $color
}
}
which will output:
.black {
background-color: #000;
}
.white {
background-color: #fff;
}
The define() function is used to define variables.

Related

ionic 2 calendar cssClass not working

I'm using https://github.com/HsuanXyz/ion2-calendar to generate a calendar in ionic. I can't make color changes to dates using dateconfig's cssClass.
Below is the code i'm using
` daysConfig() {
let _daysConfig = [
{
date:new Date(2018,0,1),
subTitle:'New Year\'s',
marked:false,
cssClass: 'my-cal'
},
{
date:new Date(2017,1,14),
subTitle:'Valentine\'s',
disable:true
},
{
date:new Date(2017,3,1),
subTitle:'April Fools',
marked:true
},
{
date:new Date(2017,3,7),
subTitle:'World Health',
marked:true
},
{
date:new Date(2017,4,31),
subTitle:'No-Smoking',
marked:true
},
{
date:new Date(2017,5,1),
subTitle:'Children\'s',
marked:true
}
];
_daysConfig.push(...this.days);
this.calendarCtrl.openCalendar({
from: new Date(2017,0,1),
to : new Date(2018,11.1),
daysConfig:_daysConfig
})
.then( (res:any) => { console.log(res) })
.catch( () => {} )
}`
css Class
.my-cal {
color: yellow
}
After a long RnD of almost 5 hour could solve this issue.
Please find the below solution in ionic
Define the below class in global.scss
.my-cal {
background-color: red !important;
}
and remember not to define this class anywhere else.
now use this in you days config as below:
let _daysConfig: DayConfig[] = [];
for (let i = 0; i < 31; i++) {
_daysConfig.push({
date: new Date(2020, 4, i + 1),
marked: false,
subTitle: `$${i + 1}`,
cssClass: 'my-cal'
})
}
Hope it will help someone :)
I just encountered the same problem, and I solved it by adding the follow style in the .scss file:
button.days-btn.my-cal {
p, small {
color: yellow;
text-decoration: underline;
font-weight: bold;
}
}
The cssClass is only added to the button that the <p> element containing the text is in.
So to properly change the color, you'll have to reference the <p> element first and assign the color to that.
Example
.ts
cssClass: 'my-cal'
.scss
.my-cal {
p {
color: green;
}
}
One of the solutions would be to add this code to your global scss/css style
ion-calendar { .my-cal{ background-color: #6E6B6B !important; p{ color: white !important; } }}
Later add "my-cal" class to wanted day.

SASS For Loop including 0

I have a for loop in SASS which loops through page classes to insert a colour break for each module. For example:
#for $i from 1 through 4 { // the loop
.m0#{$i} .module-title{
background-color: nth($m_col_lvl_01_list, $i);
}
//- end loop
}
Which compiles to:
.m01 .module-title{
background-color: green;
}
.m02 .module-title{
background-color: blue;
}
.m03 .module-title{
background-color: yellow;
}
.m04 .module-title{
background-color: orange;
}
In the task I have at the moment it includes .m00 Is there a way of including 00 in the loop?
I think you can still achieve what you want using 0 in the for loop.
$list: (green, blue, orange, red, yellow);
//loop from 0 to the length of the list which isn't hardcoded
#for $i from 0 to length($list) {
.m0#{$i} .module-title {
//simply add one to the loop index to get the correct list item
background-color: nth($list, $i + 1);
}
}
This compiles to the following CSS
.m00 .module-title {
background-color: green;
}
.m01 .module-title {
background-color: blue;
}
.m02 .module-title {
background-color: orange;
}
.m03 .module-title {
background-color: red;
}
.m04 .module-title {
background-color: yellow;
}

Use array index to change background color to element

I have created an ul element and I have put some li items inside. I want to change the background color of each li item using an array in a for loop. This is what I have, but the result is just a string :(
"use strict";
var colorArray,
i,
ulVar,
listItem;
colorArray = [
"color1",
"color2",
"color3",
"color4",
"color5",
"color6"
]
ulVar = document.createElement("ul");
ulVar.setAttribute("id", "#text-color");
ulVar.innerText = "Some unordered list"
document.body.appendChild(ulVar);
for(i = 0; i < colorArray.length; i++){
listItem = document.createElement("li");
listItem.setAttribute("class", colorArray[i]);
console.log(listItem.getAttribute("class")); //just to check what's inside
listItem.innerText = colorArray[i];
ulVar.appendChild(listItem);
}
The css code is just this:
#text-color {
color: #fff;
}
.color-1 {
background-color: #0000ff;
}
.color-2 {
background-color: #ff6600;
}
.color-3 {
background-color: #cc00cc;
}
.color-4 {
background-color: #009933;
}
.color-5 {
background-color: #669999;
}
.color-6 {
background-color: #663300;
}
I don't know how to make the colorArray[i] to return the class properties and not just string. I'm learning now so please don't judge me too hard :)

Less mixin, extract colors from array and on hover, add darken to that array

Is it possible to darken an array with colors? Like this:
#array: #color1 #color2 #color3 #color4
.color-mix(#i) when (#i > 0) {
.myClass {
li:nth-child(#{i}) {
.background-color(extract(#array, #i));
&:hover {
// THIS IS NOT WORKING, IS THERE A RIGHT APPROACH FOR THIS?
.background-color(extract(darken(#array, 5.5%, #i)));
}
}
.color-mix(#i - 1);
}
}
// Iterate
.color-mix(4);
If I understand your question correctly, yes, you can achieve that. Below is how you do it. Your code was almost correct except that instead of trying to darken the extracted value, it was trying to extract a darkened value (which is not possible).
#array: #fff #00f #ff0 #f00;
.color-mix(#i) when (#i > 0) {
.myClass {
li:nth-child(#{i}) {
.background-color(extract(#array, #i));
&:hover {
.background-color(darken(extract(#array, #i), 5.5%));
}
}
}
.color-mix(#i - 1); /* I have moved it because I think it was wrongly placed */
}
// Iterate
.color-mix(4);
One improvement that I would suggest to your code is to move the :hover selector also within the .background-color mixin like below. This makes it a bit more easier to read as there is no wrapping of a function call within another function and so on.
#array: #fff #00f #ff0 #f00;
.color-mix(#i) when (#i > 0) {
.myClass {
li:nth-child(#{i}) {
.background-color(extract(#array, #i));
}
}
.color-mix(#i - 1);
}
// Iterate
.color-mix(4);
.background-color(#color){
&{
background-color: #color;
&:hover{
background-color: darken(#color, 5.5%);
}
}
}
Even better would be this - just avoid the mixin if you can :)
#array: #fff #00f #ff0 #f00;
.color-mix(#i) when (#i > 0) {
.myClass {
li:nth-child(#{i}) {
#color: extract(#array, #i);
background-color: #color;
&:hover{
background-color: darken(#color, 5.5%);
}
}
}
.color-mix(#i - 1);
}
// Iterate
.color-mix(4);

Grouping Selectors inside of a loop using Sass

The Issue
I'm currently in a pickle. I need to group selectors inside of a Sass loop. I've tried many different ways to go about doing this such as:
body {
$store: null;
#for $i from 1 through 10 {
$store: append($store, ".offset-by-#{$i}", comma);
}
// produces content: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
#each $j in $store {
$store: unquote($j);
}
// produces .offset-by-10
}
What I'm trying to accomplish using pure Sass (no Ruby) is the following:
.offset-by-1,
.offset-by-2,
.offset-by-3,
...
.offset-by-10 { foo: bar; }
If you are a Sass god then please give me an idea of what to do here. If this is an inherent limitation of the meta-language then let me know about that too!
Considerations
I can't use anything other than a mixin to accomplish this because functions are expected to be used on a property value. Mixins, on the other hand allow the production of entire blocks of code.
Keep it simple, soldier!
%foo {
foo: bar; }
#for $i from 1 through 10 {
.offset-by-#{$i} {
#extend %foo; }}
UPD You can also have individual styles with this approach:
%foo {
foo: bar; }
#for $i from 1 through 10 {
.offset-by-#{$i} {
#extend %foo;
margin-left: 50px * $i; }}
Which results in the following CSS:
.offset-by-1, .offset-by-2, .offset-by-3, .offset-by-4, .offset-by-5, .offset-by-6, .offset-by-7, .offset-by-8, .offset-by-9, .offset-by-10 {
foo: bar; }
.offset-by-1 {
margin-left: 50px; }
.offset-by-2 {
margin-left: 100px; }
.offset-by-3 {
margin-left: 150px; }
.offset-by-4 {
margin-left: 200px; }
.offset-by-5 {
margin-left: 250px; }
.offset-by-6 {
margin-left: 300px; }
.offset-by-7 {
margin-left: 350px; }
.offset-by-8 {
margin-left: 400px; }
.offset-by-9 {
margin-left: 450px; }
.offset-by-10 {
margin-left: 500px; }
Have you tried something like this:
#mixin createNumbered($num, $className){
#for $i from 1 through $num {
.#{$className}-#{$i} {
#content;
}
}
}
#include createNumbered(10, 'foo-bar'){
color: white;
}
Updated:
#mixin createNumbered($num, $className){
$foo : '';
#for $i from 1 through $num {
$foo : $foo + '.' + $className + '-' + $i + ', ';
}
#{$foo} {
#content;
}
}
#include createNumbered(10, 'foo-bar'){
color: white;
}
This is likely overkill for what you need, but I needed to be able to add :last-child onto the class list. I built this on Clark Pan's Answer:
#mixin group-classes($start, $stop, $step, $selector, $selector-suffix, $property, $value) {
$selector-list: '';
$i: $start;
#while $i <= $stop {
$comma: ', ';
#if $i == $stop {
$comma: '';
}
$selector-list: $selector-list + $selector + '-' + $i + $selector-suffix + $comma;
$i: $i + $step;
}
#{$selector-list} {
#{$property}: #{$value}
}
}
And then to use it:
#include group-classes(1, 3, 1, '.e > .g', ':last-child', 'margin', 0);
Result:
.e > .g-1:first-child,
.e > .g-2:first-child,
.e > .g-3:first-child {
margin:0!important;
}

Resources