Less: Can't use Map inside each - css

I have following less:
#threshold:{
a:50;
b:200;
};
#themes:{
a:red;
b:blue;
};
.mymixin(#name,#color,#thrshld){
//do-something
}
each(#themes,{
.mymixin(#key,#value,#threshold[#key]);
});
By running the code, following error occurs:
RuntimeError: error evaluating function each: variable #key not found...
I'm using v3.9.0
How can I use Maps in each function?

You need to use the #map[$#property] syntax to evaluate the value of #map[#property]
.mymixin(#name, #color, #thrshld) {
.theme-#{name} {
color: #color;
width: #thrshld;
}
}
#threshold: {
a: 50;
b: 200;
};
#themes: {
a: red;
b: blue;
};
each(#themes, {
.mymixin(#key, #value, #threshold[$#key])
})

Related

SCSS Variable Name Interpolation

I'm trying to create a bunch of buttons using a loop and a map in SCSS, but I don't know if the following is possible. I couldn't find a direct answer when I searched for this.
Does anyone know if I can do this? And if I can, what in my syntax is wrong?
$button-variants:(
primary: 'primary',
secondary: 'secondary',
positive: 'positive',
negative: 'negative',
warning: 'warning'
);
#each $key,$val in $button-variants {
.c-button--#{$key} {
#include button($color-#{$key}, $color-#{$key}-highlight, true);
}
}
I'm receiving an error:
Error: Undefined variable: "$color-".
on line 54 of source/css/scss/04-components/_button.scss
>> #include button($color-#{$key}, $color-#{$key}-highlight, true);
Try something analogous to this:
/* Define the Sassy Map called $icons */
$icons: (
checkmark: a,
plus: b,
minus: c
);
/* For each key in the map, create a class */
#each $name, $value in $icons {
.icon--#{$name} {
content: $value;
}
}
And you'll get the following result:
/* For each key in the map, created a class */
.icon--checkmark {
content: "a";
}
.icon--plus {
content: "b";
}
.icon--minus {
content: "c";
}

Passing a list item in a Less variable to check the guards at single call

Is it possible to pass a list item in a Less variable to check the guard option? I have a set of rules which have guard condition to retrieve the CSS. Please refer the below sample code.
demo.less:
#obj = none;
& when (#obj = tree), (#obj = none){
.tree{
color: green;
}
}
& when (#obj = wood), (#obj = none){
.wood{
color: brown;
}
}
.......
I have a big list of rules like above code, so it takes more time to compile the less to CSS for each variable to call by the less.render function.
Is there a way to retrieve all CSS rules by call at a single time?
demo.js:
less.render(lessData, { modifyVars: { obj: "tree"} }, function (err, output) {
if (err) console.log(err);
else {
-----
-----
}
});
I would like to call something like modifyVars: { obj: ["tree","wood",...] } to get all CSS rules.

How to get a specific photosphere?

With the latest changes to Google Maps, the UI for getting a HTML snippet for embedding a photosphere into another web page has gone missing.
So, given a photosphere such as the one that can be found here, how can I embed it on a webpage using Google Maps API?
I tried two approaches:
With the approach described at https://developers.google.com/photo-sphere/web/ I wasn't able to find the panoid in the URL. I tried other random pieces of the URL to see if it would work, but it didn't.
With the approach described at https://developers.google.com/maps/documentation/javascript/examples/streetview-simple I specified the coordinates of the aforementioned photosphere, but the service returns a photosphere which is not the one I want. I want the one I authored myself.
At First:
the custom panoramas will not be published immediately, it will take some time until they will be available via the API
Your 2nd approach works for me, maybe the accuracy wasn't sufficient.
When I go to your google+-profile the location will be -23.55, -46.631, which will return a different panorama. But when I click on the map in the photo-details I get a more precise result in the page that will be opened:
-23.550201666666666,-46.63147500000002
When I use this location I get the desired panorama, the panoid is
PB0KYqVf9S0AAAQY__M_XQ
function init() {
var goo = google.maps,
map = new goo.Map(document.getElementById('map'), {
center : {lat: -23.5502017, lng: -46.631475},
zoom : 14,
noClear : true,
disableDefaultUI : true,
streetViewControl : true
}),
form = map.getDiv().querySelector('form'),
input = document.getElementById('latlng'),
desc = document.getElementById('desc'),
pano = document.getElementById('pano'),
pid = document.getElementById('pid'),
sv = new google.maps.StreetViewService();
map.setStreetView(new goo.StreetViewPanorama(pano,{
disableDefaultUI:true
}));
input.value=map.getCenter().toUrlValue();
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.push(form);
map.controls[google.maps.ControlPosition.TOP_LEFT]
.push(pano);
map.controls[google.maps.ControlPosition.TOP_CENTER]
.push(desc);
google.maps.event.addListener(map,'get_pano',function(e){
sv.getPanorama({location: e.latlng, radius: 50}, function(data,status){
map.getDiv().className=status;
if (status === goo.StreetViewStatus.OK) {
map.getStreetView().setPano(data.location.pano);
pid.value=data.location.pano;
desc.innerHTML=data.location.description;
}
else{
desc.innerHTML='no streetview available';
pid.value='';
}
google.maps.event.trigger(map,'resize');
});
});
google.maps.event.addListener(map,'click',function(e){
input.value=e.latLng.toUrlValue();
google.maps.event.trigger(form,'submit');
});
google.maps.event.addDomListener(form,'submit',function(e){
if(e)e.preventDefault();
var ll=input.value.split(','),
r=[85,180],p=['lat','lng'],f,latlng={},err=false;
if(ll.length===2){
for(var i=0;i<ll.length;++i){
f=parseFloat(ll[i]);
if(Math.abs(f)<=r[i]){
latlng[p[i]]=f;
}
else{
err=true;
}
}
}
else{
err=true;
}
if(err){
alert('invalid coordinates')
}
else{
google.maps.event.trigger(map,'get_pano',{latlng:latlng})
}
return false;
});
google.maps.event.trigger(form,'submit');
}
html, body,#map {
height: 100%;
margin: 0;
padding: 0;
}
#pano{
height:100px;
width:150px;
}
#pid,#pano{
display:none;
}
#map>form{
display:none;
}
#pid{
background:Chartreuse;
}
#map.OK #pid,#map.OK #pano,#map.OK #desc{
display:block;
}
#desc{
background:tomato !important;
}
#map.OK #desc{
background:rgba(0,255,0, .8) !important;
}
#map form,#desc{
text-align:center;
padding:6px;
background:rgba(255,255,255, .8);
border:1px solid #000;
border-radius:4px;
}
#desc{
background:rgba(255,0,0, .8);
}
#map form,#pano{
margin:4px;
}
<div id="map">
<form>
<input id="latlng" placeholder="latitude,longitude"><br/><input type="submit"><br/>
<input id="pid" readonly>
<div id="pano"></div>
<div id="desc"></div>
</form>
</div>
<script async defer
src="https://maps.googleapis.com/maps/api/js?v=3&callback=init">
</script>

CodeKit 2 - compiling less with empty lines in code

I'm using Codekit 2.1.8 to compile my LESS files. In my LESS files I have empty lines and I want to have them in compilied CSS file too, but Codekit seems to delete them. I can't find any options in Codekit related to this issue.
Example:
LESS file:
p {
font-size: 14px;
}
a {
color: red;
}
Compilied CSS file with Codekit:
p {
font-size: 14px;
}
a {
color: red;
}
When using the default command line or client side you can easily add your own plugins since v2. Less preserves /**/ comments.
Add in your LESS code for instance /*3*/ for 3 newlines.
Now write the plugin, call this file less-plugin-add-newlines.js:
var getCommentsProcessor = require("./comments-processor");
module.exports = {
install: function(less, pluginManager) {
var CommentsProcessor = getCommentsProcessor(less);
pluginManager.addPostProcessor(new CommentsProcessor());
}
};
Than write the comments-processor.js:
String.prototype.repeat = function( num )
{
return new Array( num + 1 ).join( this );
}
module.exports = function(less) {
function CommentProcessor(options) {
this.options = options || {};
};
CommentProcessor.prototype = {
process: function (css) {
var r = new RegExp("(\\/\\*)([0-9]+)(\\*\\/)","g");
return css.replace(r,function(m1,m2,m3){ return "\n".repeat(m3*1-1); });
}
};
return CommentProcessor;
};
less
p1 {
p:3;
}
/*3*/
p2 {
p:3;
}
/*4*/
p2 {
p:3;
}
The preceding will compile into when running lessc --plugin=less-plugin-add-newlines.js index.less:
p1 {
p: 3;
}
p2 {
p: 3;
}
p2 {
p: 3;
}

CSSBuilder can be used without Griffon?

I have a standalone Swing application and I'm using Groovy as programing language.
Trying to apply styles using CSS and searching for some tool for this purpose, I've found CSSBuilder.
The problem is that CSSBuilder comes integrated with Griffon framework, so I cannot use all of its features isolated from Griffon, such as 'cssClass' selector.
Therefore my question is simply: has anyone managed to do something like this?
Just wrote a quick test, and this seems to work:
#GrabResolver( name='codehaus', root='http://repository.codehaus.org' )
#Grab( 'org.codehaus.griffon:cssbuilder:0.4' )
import griffon.builder.css.*
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
def style = '''* {
background-color: red;
}
jbutton {
background-color: blue;
}
.active {
color: green ;
font-size: 50%;
}
jlabel {
color: pink ;
font-size: 200% ;
}'''
Class klass = javax.swing.JComponent
if( !AbstractSyntheticMetaMethods.hasBeenEnhanced(klass) ) {
AbstractSyntheticMetaMethods.enhance(klass,[
"getCssClass": {-> delegate.getClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY) },
"setCssClass": { String cssClass -> delegate.putClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY, cssClass) }
])
}
new SwingBuilder().edt {
int count = 0
def frame = frame( title:'CSS Test', size:[ 300, 300 ], show: true ) {
borderLayout()
textlabel = label(text:"Click the button!", constraints: BL.NORTH)
button(text:'Click Me',
cssClass: 'active',
actionPerformed: {count++; textlabel.text = "Clicked ${count} time(s)."; println "clicked"},
constraints:BL.SOUTH)
}
CSSDecorator.applyStyle( style, frame )
}
The meta-class enhancing code I took from the source of CSSBuilder

Resources