Reputation: 1085
I'm just starting with Polymer (with a Rails backend) and I was wondering, can I apply a style on a polymer element, like normal html ?
My goal is to make a loop and have each card with a different header background-color.
I know I could define my different custom-styles and make an array of my classes to pick one during the loop, but I just want to know if there is a way to do something with less code like :
colors = ['red','blue','green']
<paper-card heading="<%= foo.name %>" elevation="3" style="--paper-card-header-color:<%= colors.sample %>">
Maybe it's too old-fashion.
Any clue ?
Upvotes: 0
Views: 279
Reputation: 8042
You can create your array of custom paper-card header colors, like this:
colors = ['red','blue','green']
<style is="custom-style">
paper-card {
}
<% color in colors do %>
.<%= color %> { --paper-card-header-color: <%= color %> }
<% end %>
</style>
This will produce these custom color styles:
<style is="custom-style">
<% color in colors do %>
.red { --paper-card-header-color: <%= red %> }
.blue { --paper-card-header-color: <%= blue %> }
.green { --paper-card-header-color: <%= green %> }
<% end %>
</style>
This will work for CSS named colors. If you want to use the full range of CSS colors, you can detect the #XXXXXX
format and name color styles appropriately:
colors = ['red','blue','green','#c0c0c0','B0306F']
<style is="custom-style">
paper-card {
}
<% colors.each_with_index do |color,index| %>
<% if color =~ /^#?[0-9a-f]$/i %>
<% color = color.gsub(/\D+/, '').downcase %>
<% colors[index] = color %>
.color-<%= color %> { --paper-card-header-color: #<%= color %> }
<% else %>
.<%= color %> { --paper-card-header-color: <%= color %> }
<% end %>
<% end %>
</style>
Note that in this example, the colors
array is modified with the name of the color class. A separate array of color class names could be kept, if desired.
You can apply these styles while processing the cards, by applying the appropriate color class:
<% cards.each do |card| %>
<paper-card heading="<%= card.title %>" class="<%=colors.sample%>">
<% end %>
If you want to apply a random color each time through the loop, your approach of using Array#sample
is very sensible and smart coding. The Array#sample
method will give you a pseudo-random color from the list; however, you may get repeated colors more frequently than you like, especially with small color lists.
For example, I ran this code:
colors = ['red','blue','green']
20.times { puts "#{colors.sample}" }
and I got this output:
green
green
green
blue
red
green
red
green
blue
green
red
red
blue
green
blue
red
red
green
red
blue
If you'd prefer to have unique colors, but in random order, you can use Array#shuffle
to re-order the list of colors randomly:
random_colors = colors.shuffle
<% cards.each do |card| %>
<paper-card heading="<%= card.title %>" class="<%= random_colors.shift %>">
<% end %>
If you have more cards to produce than colors, you might want to make random_colors
be large enough to accommodate the entire run of cards:
random_colors = colors.shuffle.cycle((cards.length.to_f / colors.length.to_f).ceil).inject([]) {|array, color| array << color }
<% cards.each do |card| %>
<paper-card heading="<%= card.title %>" class="<%= random_colors.shift %>">
<% end %>
In this case, if cards
was a run of 7 cards, you would have a random_colors
array of 9 colors, repeating the 3 random colors 3 times.
You can also reset the random_colors
array inside the loop to make multiple randomly ordered runs:
colors = ['red','blue','green']
random_colors = []
<% cards.each do |card| %>
random_colors = colors.shuffle if random_colors.length == 0
<paper-card heading="<%= card.title %>" class="<%= random_colors.shift %>">
<% end %>
This will produce a new randomly ordered array each time random_colors
is empty. You definitely have options, and which is a better solution depends on your goals and what you feel works in your situation.
Upvotes: 0
Reputation: 1085
So, Apparently Polymer don't like inline css.
I've come to this, I
For the record, I tried to solve the problem and I came to this (ugly) solution : (I think we can do it in a better way using javascript.)
colors_key = ['leonardo','donatello','mickelangelo','raphael','casey']
colors = {colors_key[0]=>'blue',colors_key[1]=>'purple',colors_key[2]=>'orange',colors_key[3]=>'red',colors_key[4]=>'green'}
<style is="custom-style">
<% colors.each do |k,v| %>
<%= ".#{k}" %> { --paper-card-header-color: <%= "#{v}" %> }
<% end %>
</style>
<paper-card heading="<%= foo.name %>" class="<%=colors_key.sample%>">
Question close, but any improvement welcome !
Upvotes: 0
Reputation: 7167
That code works?
If so, the same with less code would be:
<paper-card heading="<%= foo.name %>" elevation="3" style="--paper-card-header-color:<%= %w(red blue green).sample %>">
But why do you want less code? A "better" (some might say) goal is to have more readable code, in that case I think a helper would be a better choice:
<paper-card heading="<%= foo.name %>" elevation="3" style="--paper-card-header-color:<%= random_color %>">
And define a helper method random_color
.
The code is not "old school" is up to you to do the "random" color pick in Ruby, or do it on JavaScript, I don't think there is any other way.
Upvotes: 0