Class: Railsboot::AvatarComponent

Inherits:
Component
  • Object
show all
Defined in:
app/components/railsboot/avatar_component.rb

Overview

ViewComponent: renders the avatar block.

Constant Summary collapse

SHAPES =

Returns the supported avatar shapes.

Returns:

  • (Array<String>)

    the supported avatar shapes

%w[circle rounded square].freeze
DEFAULT_SHAPE =

Returns the default avatar shape.

Returns:

  • (String)

    the default avatar shape

"circle".freeze
DEFAULT_SIZE =

Returns the default avatar size in pixels.

Returns:

  • (Integer)

    the default avatar size in pixels

32
COLORS =

Returns the supported background colors.

Returns:

  • (Array<String>)

    the supported background colors

%w[primary secondary light dark].freeze
DEFAULT_COLOR =

Returns the default background color.

Returns:

  • (String)

    the default background color

"primary".freeze

Instance Method Summary collapse

Constructor Details

#initialize(src: "", letter: "", alt: "", shape: DEFAULT_SHAPE, size: DEFAULT_SIZE, color: DEFAULT_COLOR, href: "", **html_attributes) ⇒ AvatarComponent

Returns a new instance of AvatarComponent.

Parameters:

  • src (String) (defaults to: "")

    the src option

  • letter (String) (defaults to: "")

    the letter option

  • alt (String) (defaults to: "")

    the alt option

  • shape (String) (defaults to: DEFAULT_SHAPE)

    the shape option

  • size (String) (defaults to: DEFAULT_SIZE)

    the size option

  • color (String) (defaults to: DEFAULT_COLOR)

    the color option

  • href (String) (defaults to: "")

    the href option

  • html_attributes (Hash)

    additional HTML attributes applied to the rendered element

Options Hash (**html_attributes):

  • :class (String)

    additional CSS classes, merged with the component's own classes

  • :style (String)

    additional HTML attribute forwarded to the element



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'app/components/railsboot/avatar_component.rb', line 28

def initialize(src: "", letter: "", alt: "", shape: DEFAULT_SHAPE, size: DEFAULT_SIZE, color: DEFAULT_COLOR, href: "", **html_attributes)
  @alt = alt
  @shape = fetch_or_raise(shape, SHAPES)
  @size = size
  @color = fetch_or_raise(color, COLORS)
  @letter = letter
  @src = src.presence || letter_to_svg_base64(letter)
  # When src and letter are both supplied, keep the letter SVG as a
  # client-side fallback so a broken remote image (e.g. ImageKit 404)
  # degrades to initials instead of overflowing alt text.
  @fallback_src = src.present? && letter.present? ? letter_to_svg_base64(letter) : nil
  @href = href
  @html_attributes = html_attributes

  @html_attributes[:class] = class_names(
    "position-relative",
    "d-inline-block",
    "bg-#{@color}",
    radius_class,
    html_attributes.delete(:class)
  )

  @html_attributes[:style] = [
    html_attributes[:style],
    "width: #{@size}px; height: #{@size}px; box-sizing: content-box; overflow: hidden; vertical-align: middle;"
  ].compact.join(" ")
end

Instance Method Details

#image_data_attributesHash

Returns Stimulus data attributes wiring the client-side letter-SVG
fallback for a broken remote image; empty when no fallback applies.

Returns:

  • (Hash)

    Stimulus data attributes wiring the client-side letter-SVG
    fallback for a broken remote image; empty when no fallback applies



58
59
60
61
62
# File 'app/components/railsboot/avatar_component.rb', line 58

def image_data_attributes
  return {} unless @fallback_src

  { controller: "avatar-fallback", avatar_fallback_src_value: @fallback_src }
end

#letter_to_svg_base64(letter = "") ⇒ String (protected)

Builds an inline SVG data-URI rendering the given letter as initials.

Parameters:

  • letter (String) (defaults to: "")

    the letter to render inside the SVG

Returns:

  • (String)

    a base64-encoded data:image/svg+xml URI



85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/components/railsboot/avatar_component.rb', line 85

def letter_to_svg_base64(letter = "")
  font_color = @color === "light" ? "black" : "white"
  svg_content = <<~SVG
    <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
      <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle" font-family="Arial" font-size="40" dy=".1em" dominant-baseline="middle" fill="#{font_color}">
        #{letter}
      </text>
    </svg>
  SVG

  "data:image/svg+xml;base64,#{Base64.strict_encode64(svg_content)}"
end

#link?Boolean

Returns whether the avatar renders wrapped in a link.

Returns:

  • (Boolean)

    whether the avatar renders wrapped in a link



75
76
77
# File 'app/components/railsboot/avatar_component.rb', line 75

def link?
  @href.present?
end

#radius_classString

Returns the Bootstrap border-radius class matching the configured shape.

Returns:

  • (String)

    the Bootstrap border-radius class matching the configured shape



65
66
67
68
69
70
71
72
# File 'app/components/railsboot/avatar_component.rb', line 65

def radius_class
  shape_classes = {
    "circle" => "rounded-circle",
    "rounded" => "rounded-4",
    "square" => "rounded-0"
  }
  shape_classes[@shape]
end