Last active
August 14, 2024 22:46
A Rails view component to display an initials avatar using tailwindcss and dev.to color generating algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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