Skip to content

Instantly share code, notes, and snippets.

@Yardboy
Last active August 14, 2024 22:46
A Rails view component to display an initials avatar using tailwindcss and dev.to color generating algorithm
# frozen_string_literal: true
class AvatarComponent < ApplicationComponent
# https://dev.to/admitkard/auto-generate-avatar-colors-randomly-138j
DEFAULT_COLOR = [240, 2, 85].freeze
HRANGE = [0, 360].freeze
SRANGE = [40, 60].freeze
LRANGE = [40, 60].freeze
attr_reader :user, :size
delegate :email, :first_name, :last_name, to: :user, allow_nil: true
erb_template <<-ERB
<div style="background-color: <%= color %>" class="relative inline-flex items-center justify-center w-<%= width %> h-<%= width %> overflow-hidden rounded-full">
<span class="<%= text %> font-medium text-neutral-50"><%= initials %></span>
</div>
ERB
def initialize(user:, size: :lg)
@user = user
@size = size
end
def initials
return unless user
"#{first_name[0]}#{last_name[0]}".upcase
end
def color
"hsl(#{hsl[0]}, #{hsl[1]}%, #{hsl[2]}%)"
end
def text
TEXT_SIZES[size] || TEXT_SIZES[:base]
end
def width
WIDTHS[size] || WIDTHS[:base]
end
def hsl
@hsl ||= user.nil? ? DEFAULT_COLOR : hashed_color
end
def hashed_color
[
normalize(hash: hash_of_string, range: HRANGE),
normalize(hash: hash_of_string, range: SRANGE),
normalize(hash: hash_of_string, range: LRANGE)
]
end
def hash_of_string
@hash_of_string ||= email.chars.inject(0) do |hash, letter|
letter.ord + ((hash << 5) - hash)
end
end
def normalize(hash:, range:)
((hash % (range.last - range.first)) + range.first).floor
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment