DEV Community

Cover image for Create a String to Color Helper with Ruby (and Rails)
Rails Designer
Rails Designer

Posted on • Edited on • Originally published at railsdesigner.com

1

Create a String to Color Helper with Ruby (and Rails)

This article was originally published on Rails Designer.


In the latest version (v1) of Rails Designer I added a Chat Messages Component.

For one of the provided variants I wanted to have a different background- and text-color based on the user's name. I like this kind of “random” customizations to UI components, as it gives an otherwise monotone UI layout some sparkle. In the context of chat messages it works well too differentiate between the different messages from users.

I used a similar technique for the AvatarComponent. Here, when no profile picture is available (attached), it calculates the color for the user name's initial.

I typically calculate these colors at runtime, but I can imagine, when your app grows, to store them alongside the user in some sort of preferences model.

Rails Designer is a professionally designed UI components library for Rails. Built with ViewComponent. Designed with Tailwind CSS. Enhanced with Hotwire. Build beautiful, faster.

For the example of the chat messages I wanted to pick one of Tailwind CSS' colors. This is because the the background- and text color is set as follows:

# …

def initialize(name:)
  @name = name
  @color = string_to_color(name)
end

def chat_css = class_names("px-3 py-1 rounded", states[@color])

def states
  {
    red: "bg-red-100 text-red-800",
    blue: "bg-blue-100 text-blue-800"
    # …
  }
end
Enter fullscreen mode Exit fullscreen mode

(example simplified for demonstration purposes)

So how does the string_to_color helper look like? It's pretty straight-forward. Let's see:

# app/helpers/string_to_color.rb
module StringToColorHelper
  def string_to_color(string, colors: TAILWIND_COLORS)
    hash_value = string.downcase.each_char.sum(&:ord)
    index = hash_value % colors.length

    colors[index]
  end

  private

  TAILWIND_COLORS = %w[
    slate gray zinc neutral stone
    red orange amber yellow lime green emerald teal cyan sky blue indigo violet purple fuchsia pink rose
  ].freeze
end
Enter fullscreen mode Exit fullscreen mode

It calculates a hash value (hash_value) from the given string by converting each character to its ASCII value. So given a string of Example will output:

"Example".downcase.each_char # ['e', 'x', 'a', 'm', 'p', 'l', 'e']
Enter fullscreen mode Exit fullscreen mode

Then, based on the ASCII characters, the sum is returned.

"Example".downcase.each_char.sum(&:ord)
# `&:ord` → [101, 120, 97, 109, 112, 108, 101]
# `sum()` → 748
Enter fullscreen mode Exit fullscreen mode

This sum is then used to select an index from the colors array. Using the modulus of the hash_value (hash_value % colors.length) with the length of the colors array ensures the index is always within the bounds of the array.

By default this uses the TAILWIND_COLORS constant, thus always returning slate, gray, red, etc. But you can also pass another array with hexadecimal colors (directly) to the method. Like this: string_to_color("Example", colors: ["#3498DB", "#2ECC71", "#F1C40F"]).

V1 of Rails Designer comes with this new helper out of the box. Check out the docs for more details.

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (1)

Collapse
 
railsdesigner profile image
Rails Designer

While this method is focused on colors, there's no reason you could pass something else than a colors-array. How could you see the same technique used with a different "source" than colors?

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay