Avatar
A user avatar with image and a text/initials fallback.
Installation
bin/rails g wabi:add avatarExample
render Components::UI::Avatar.new do
render Components::UI::AvatarImage.new(src: "/avatar-sample.svg", alt: "Jane Doe")
render Components::UI::AvatarFallback.new { "JD" }
end
OO
render Components::UI::Avatar.new do
render Components::UI::AvatarFallback.new { "OO" }
end
Source
app/components/ui/avatar.rb
# frozen_string_literal: true
module Components
module UI
class Avatar < Wabi::Base
variants { base "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full" }
def initialize(**attrs) = @attrs = attrs
def view_template(&)
user_class = @attrs.delete(:class)
span(**@attrs, class: merge_class(tokens, user_class), &)
end
end
end
end
app/components/ui/avatar_image.rb
# frozen_string_literal: true
module Components
module UI
class AvatarImage < Wabi::Base
variants { base "absolute inset-0 aspect-square h-full w-full object-cover" }
# Pass alt: with the person/entity name for a meaningful accessible name.
# The default empty alt marks the image decorative (hidden from AT) — fine
# when an adjacent AvatarFallback or nearby text already names the avatar.
def initialize(src:, alt: "", **attrs)
@src = src
@alt = alt
@attrs = attrs
end
def view_template
user_class = @attrs.delete(:class)
img(src: @src, alt: @alt, **@attrs, class: merge_class(tokens, user_class))
end
end
end
end
app/components/ui/avatar_fallback.rb
# frozen_string_literal: true
module Components
module UI
class AvatarFallback < Wabi::Base
variants { base "flex h-full w-full items-center justify-center rounded-full bg-muted" }
def initialize(**attrs) = @attrs = attrs
def view_template(&)
user_class = @attrs.delete(:class)
span(**@attrs, class: merge_class(tokens, user_class), &)
end
end
end
end
Accessibility
- the alt: attribute on AvatarImage is required for screen readers; pass a meaningful name or empty string for decorative use.
- when the image fails to load, AvatarFallback renders automatically (usually initials).
- for purely decorative avatars in lists, consider aria-hidden="true" on the wrapper to suppress redundant announcements.