Class: Plutonium::UI::Avatar
- Inherits:
-
Component::Base
- Object
- Component::Base
- Plutonium::UI::Avatar
- Defined in:
- lib/plutonium/ui/avatar.rb
Overview
Renders a profile/avatar image for a subject.
Avatar(user) # Navii fallback seeded from the record
Avatar(user, src: :photo) # user.photo if present, else Navii fallback
Avatar(user, src: user.photo) # pass the attachment/uploader/URL directly
Avatar("acme-team") # a String subject is a deterministic seed
Avatar("https://.../p.png") # a URL-shaped subject is shown as the image
Avatar(src: "https://.../p.png") # a bare image, no subject/fallback
The positional subject is the identity the fallback is derived from: a record or a String, hashed to an opaque, PII-free seed. As a convenience, a URL-shaped String subject is treated as src (the image) instead. src is the image to show and may be:
-
a Symbol naming a method on the subject (e.g.
:avatar->subject.avatar). This is a contract: the subject must respond to it (raises NoMethodError otherwise), so only use a Symbolsrcwith a record subject. -
an ActiveStorage attachment, active_shrine/Shrine uploader, or URL String
Resolution order: the resolved src, then a Navii avatar seeded from the subject, then a generic user icon when there is nothing to show.
Constant Summary collapse
- SIZES =
Pixel dimensions per semantic size, plus the matching Tailwind width/height utilities (needed because the preflight resets ‘img { height: auto }`, so width/height attributes alone don’t pin the rendered size).
{xs: 24, sm: 32, md: 40, lg: 48, xl: 64}.freeze
- SIZE_CLASSES =
{xs: "w-6 h-6", sm: "w-8 h-8", md: "w-10 h-10", lg: "w-12 h-12", xl: "w-16 h-16"}.freeze
Class Method Summary collapse
-
.resolve_image_src(value, helpers = nil) ⇒ Object
Resolve an image value to a URL string.
Instance Method Summary collapse
-
#initialize(subject = nil, src: nil, size: :md, alt: nil, **attributes) ⇒ Avatar
constructor
A new instance of Avatar.
- #view_template ⇒ Object
Methods included from Component::Behaviour
Methods included from Component::Tokens
Methods included from Component::Kit
#BuildActionButton, #BuildActionsDropdown, #BuildAvatar, #BuildBlock, #BuildBreadcrumbs, #BuildBulkActionsToolbar, #BuildColorModeSelector, #BuildDynaFrameContent, #BuildDynaFrameHost, #BuildEmptyCard, #BuildFrameNavigatorPanel, #BuildModalCentered, #BuildModalSlideover, #BuildPageHeader, #BuildPanel, #BuildRowActionsDropdown, #BuildSkeletonTable, #BuildTabList, #BuildTableFilterPills, #BuildTableInfo, #BuildTablePagination, #BuildTableScopesBar, #BuildTableScopesPills, #BuildTableSearchBar, #BuildTableToolbar, #BuildTableViewSwitcher, #method_missing, #respond_to_missing?
Constructor Details
#initialize(subject = nil, src: nil, size: :md, alt: nil, **attributes) ⇒ Avatar
Returns a new instance of Avatar.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/plutonium/ui/avatar.rb', line 71 def initialize(subject = nil, src: nil, size: :md, alt: nil, **attributes) # A URL-shaped positional subject is really an image, not an identity: # route it to src so Avatar("https://…/p.png") shows the image rather # than hashing the URL into a seed. if src.nil? && subject.is_a?(String) && subject.start_with?("http", "/") src = subject subject = nil end @subject = subject @src = src @size = size @alt = alt @attributes = attributes end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Plutonium::UI::Component::Kit
Class Method Details
.resolve_image_src(value, helpers = nil) ⇒ Object
Resolve an image value to a URL string. Supports:
-
ActiveStorage attachments -> helpers.url_for (they aren’t routable via #url)
-
active_shrine / other ActiveStorage-style wrappers -> value.url
-
Bare Shrine::UploadedFile, CarrierWave, etc. (respond to :url) -> value.url
-
Plain URL strings (“https://…” or “/uploads/…”)
Exposed as a module method so collaborators (e.g. Grid::Card) can reuse the resolution without instantiating the component.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/plutonium/ui/avatar.rb', line 43 def self.resolve_image_src(value, helpers = nil) return nil if value.nil? # ActiveStorage is the only supported source that must go through Rails # routing rather than its own #url. It has to be matched *before* the # generic attached?/url checks, because ActiveStorage-compatible wrappers # (e.g. active_shrine) respond to BOTH attached? and url, and those should # resolve via their own #url instead. if (value) return value.attached? ? helpers&.url_for(value) : nil end if value.respond_to?(:attached?) # active_shrine & other AS-style wrappers value.attached? ? value.url : nil elsif value.respond_to?(:url) # bare Shrine::UploadedFile, CarrierWave, ... value.url elsif value.is_a?(String) && value.start_with?("http", "/") value end rescue ArgumentError, URI::InvalidURIError nil end |
Instance Method Details
#view_template ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/plutonium/ui/avatar.rb', line 87 def view_template url = resolved_src || navii_url if url img( src: url, alt: alt_text.to_s, width: pixel_size, height: pixel_size, loading: "lazy", **sized_attributes("rounded-full object-cover bg-[var(--pu-surface-alt)] shrink-0") ) else div(**sized_attributes("rounded-full bg-[var(--pu-surface-alt)] text-[var(--pu-text-muted)] flex items-center justify-center shrink-0")) do render Phlex::TablerIcons::User.new(class: "w-2/3 h-2/3") end end end |