disastrous-charly
disastrous-charly

Reputation: 1085

Random colors on polymer paper-cards

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

Answers (3)

Michael Gaskill
Michael Gaskill

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

disastrous-charly
disastrous-charly

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

Leonel Gal&#225;n
Leonel Gal&#225;n

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

Related Questions