Module: Layered::Ui::PopoverHelper
- Defined in:
- app/helpers/layered/ui/popover_helper.rb
Defined Under Namespace
Classes: PopoverBuilder
Instance Method Summary collapse
-
#l_ui_popover(id: nil, placement: :bottom, align: :start, container: {}, &block) ⇒ Object
Renders a floating panel anchored to a trigger button, built on the native HTML
popoverattribute.
Instance Method Details
#l_ui_popover(id: nil, placement: :bottom, align: :start, container: {}, &block) ⇒ Object
Renders a floating panel anchored to a trigger button, built on the
native HTML popover attribute. Showing, hiding, light-dismiss, and
Escape-to-close are all handled by the browser; the l-ui--popover
Stimulus controller only computes placement (with auto-flip near
viewport edges).
<%= l_ui_popover(placement: :bottom) do |p| %>
<% p.trigger(class: "l-ui-button l-ui-button--outline") do %>
Options
<% end %>
<p>Popover content.</p>
<% end %>
Note: use <% p.trigger %> (without the equals sign) so its content is
captured by the builder rather than written to the body buffer.
Options:
id: (String) DOM id for the popover element; defaults to an auto-generated id.
placement: (Symbol) :top, :bottom (default), :left, or :right. Flips automatically if it would overflow the viewport.
align: (Symbol) :start (default) flushes the popover's leading edge with the trigger's; :end flushes its trailing edge instead
(e.g. placement: :bottom, align: :end hangs the popover down and to the left of a trigger at the right end of a row).
container: (Hash) Extra HTML attributes for the wrapping <div>.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/helpers/layered/ui/popover_helper.rb', line 26 def l_ui_popover(id: nil, placement: :bottom, align: :start, container: {}, &block) id ||= "l-ui-popover-#{SecureRandom.hex(4)}" builder = PopoverBuilder.new(self, id: id) body_content = capture { block.call(builder) } container_attrs = container.deep_dup container_data = container_attrs[:data] || {} existing_controller = container_data.delete(:controller) || container_data.delete("controller") container_data[:controller] = [existing_controller, "l-ui--popover"].compact.reject(&:empty?).join(" ") container_data[:"l-ui--popover-placement-value"] = placement container_data[:"l-ui--popover-align-value"] = align container_attrs[:data] = container_data tag.div(**container_attrs) do safe_join([ builder.trigger_html || ActiveSupport::SafeBuffer.new, render_popover(builder, body_content) ]) end end |