In the latest (v1) version 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.
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
(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
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']
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
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.