diff --git a/app/templates/shared/popovers/triggers/_button.html.erb b/app/templates/shared/popovers/triggers/_button.html.erb new file mode 100644 index 00000000..db6795bd --- /dev/null +++ b/app/templates/shared/popovers/triggers/_button.html.erb @@ -0,0 +1,4 @@ +<%= tag.button type: :button, class: classes, interestfor: tip, popovertarget: target do %> + <%= image_tag icon_uri, class: :icon, width:, height:, loading: :lazy %> + <%= yield if block_given? %> +<% end %> diff --git a/app/views/scopes/popover_trigger_button.rb b/app/views/scopes/popover_trigger_button.rb new file mode 100644 index 00000000..0c45093a --- /dev/null +++ b/app/views/scopes/popover_trigger_button.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Terminus + module Views + module Scopes + # A customizable popover trigger button. + class PopoverTriggerButton < Hanami::View::Scope + def classes = locals.fetch __method__, "bit-popover-trigger" + + def height = locals.fetch __method__, 15 + + def icon = locals.fetch __method__, :info + + def icon_uri = "icons/#{icon}.svg" + + def render(path = "shared/popovers/triggers/button") = super + + def target = locals[__method__].then { "popover-#{it}" if it } + + def tip = locals[__method__].then { "tooltip-action-#{it}" if it } + + def width = locals.fetch __method__, 15 + end + end + end +end diff --git a/spec/app/views/scopes/popover_trigger_button_spec.rb b/spec/app/views/scopes/popover_trigger_button_spec.rb new file mode 100644 index 00000000..d17cf5ef --- /dev/null +++ b/spec/app/views/scopes/popover_trigger_button_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +require "hanami_helper" + +RSpec.describe Terminus::Views::Scopes::PopoverTriggerButton do + subject(:scope) { described_class.new locals:, rendering: Terminus::View.new.rendering } + + let(:locals) { {icon: :info} } + + describe "#classes" do + it "answers default classes" do + expect(scope.classes).to eq("bit-popover-trigger") + end + + it "answers custom classes" do + locals[:classes] = "one two three" + expect(scope.classes).to eq("one two three") + end + end + + describe "#height" do + it "answers default height" do + expect(scope.height).to eq(15) + end + + it "answers custom height" do + locals[:height] = 30 + expect(scope.height).to eq(30) + end + end + + describe "#icon" do + it "answers default icon" do + expect(scope.icon).to eq(:info) + end + + it "answers custom icon" do + locals[:icon] = :test + expect(scope.icon).to eq(:test) + end + end + + describe "#icon_uri" do + it "answers default URI" do + expect(scope.icon_uri).to eq("icons/info.svg") + end + + it "answers custom URI" do + locals[:icon] = :test + expect(scope.icon_uri).to eq("icons/test.svg") + end + end + + describe "#render" do + it "renders button" do + expect(scope.render).to include(%(