Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ application.register("ruby-ui--accordion", RubyUi__AccordionController)
import RubyUi__AlertDialogController from "./ruby_ui/alert_dialog_controller"
application.register("ruby-ui--alert-dialog", RubyUi__AlertDialogController)

import RubyUi__AvatarController from "./ruby_ui/avatar_controller"
application.register("ruby-ui--avatar", RubyUi__AvatarController)

import RubyUi__CalendarController from "./ruby_ui/calendar_controller"
application.register("ruby-ui--calendar", RubyUi__CalendarController)

Expand Down
29 changes: 29 additions & 0 deletions docs/app/javascript/controllers/ruby_ui/avatar_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static targets = ["image", "fallback"];

connect() {
if (!this.hasImageTarget) return;

if (this.imageTarget.complete && this.imageTarget.naturalWidth > 0) {
this.showImage();
} else {
this.showFallback();
}
}

showImage() {
this.imageTargets.forEach((image) => image.classList.remove("hidden"));
this.fallbackTargets.forEach((fallback) =>
fallback.classList.add("hidden"),
);
}

showFallback() {
this.imageTargets.forEach((image) => image.classList.add("hidden"));
this.fallbackTargets.forEach((fallback) =>
fallback.classList.remove("hidden"),
);
}
}
3 changes: 3 additions & 0 deletions gem/lib/ruby_ui/avatar/avatar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def view_template(&)

def default_attrs
{
data: {
controller: "ruby-ui--avatar"
},
class: ["relative flex shrink-0 overflow-hidden rounded-full", @size_classes]
}
end
Expand Down
29 changes: 29 additions & 0 deletions gem/lib/ruby_ui/avatar/avatar_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static targets = ["image", "fallback"];

connect() {
if (!this.hasImageTarget) return;

if (this.imageTarget.complete && this.imageTarget.naturalWidth > 0) {
this.showImage();
} else {
this.showFallback();
}
}

showImage() {
this.imageTargets.forEach((image) => image.classList.remove("hidden"));
this.fallbackTargets.forEach((fallback) =>
fallback.classList.add("hidden"),
);
}

showFallback() {
this.imageTargets.forEach((image) => image.classList.add("hidden"));
this.fallbackTargets.forEach((fallback) =>
fallback.classList.remove("hidden"),
);
}
}
3 changes: 3 additions & 0 deletions gem/lib/ruby_ui/avatar/avatar_fallback.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ def view_template(&)

def default_attrs
{
data: {
ruby_ui__avatar_target: "fallback"
},
class: "flex h-full w-full items-center justify-center rounded-full bg-muted"
}
end
Expand Down
6 changes: 5 additions & 1 deletion gem/lib/ruby_ui/avatar/avatar_image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ def view_template
def default_attrs
{
loading: "lazy",
class: "aspect-square h-full w-full",
data: {
ruby_ui__avatar_target: "image",
action: "load->ruby-ui--avatar#showImage error->ruby-ui--avatar#showFallback"
},
class: "hidden aspect-square h-full w-full",
alt: @alt,
src: @src
}
Expand Down
5 changes: 5 additions & 0 deletions gem/test/ruby_ui/avatar_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@ def test_render_with_all_items
end

assert_match(/joeldrapper/, output)
assert_match(/data-controller="ruby-ui--avatar"/, output)
assert_match(/data-ruby-ui--avatar-target="image"/, output)
assert_match(/load->ruby-ui--avatar#showImage error->ruby-ui--avatar#showFallback/, output)
assert_match(/data-ruby-ui--avatar-target="fallback"/, output)
assert_match(/hidden aspect-square/, output)
end
end