Module: Layered::Ui::TagHelper
- Defined in:
- app/helpers/layered/ui/tag_helper.rb
Defined Under Namespace
Classes: TagBuilder
Instance Method Summary collapse
-
#l_ui_tag(rounded: false, container: {}, &block) ⇒ Object
Renders an interactive tag - e.g.
Instance Method Details
#l_ui_tag(rounded: false, container: {}, &block) ⇒ Object
Renders an interactive tag - e.g. an email recipient or an active
filter. Visually related to l-ui-badge, but a distinct control: a
badge is a static styled span, while a tag is a container whose
segments (label, remove) are separately interactive.
<%= l_ui_tag do |t| %>
<% t.text "alice@example.com" %>
<% t.remove aria: { label: "Remove alice@example.com" } %>
<% end %>
A tag may carry a popover. The whole tag becomes the placement target
(so the popover aligns with the tag rather than the segment inside
it), and button segments open it via popovertarget:
<%= l_ui_tag do |t| %>
<% t.button(aria: { label: "Edit status filter" }) do %>
Status: Active
<% end %>
<% t.remove remove_filter_path, aria: { label: "Remove status filter" } %>
<% t.popover do %>
<p>Filter controls.</p>
<% end %>
<% end %>
Note: use <% t.button %> (without the equals sign) so segment content
is captured by the builder rather than written to the body buffer.
Segments render in the order they are declared; the popover element is
always appended last. Give icon-only segments (such as t.remove) an
aria-label so they have an accessible name.
Options:
rounded: (Boolean) Pill shape (matching +l-ui-badge--rounded+); defaults to false for the subtle badge shape.
container: (Hash) Extra HTML attributes for the wrapping <div>.
Builder methods:
t.text(content = nil, **options, &block) Static label segment ().
t.button(**options, &block) Button segment; opens the tag's popover when one is declared.
t.link(url, **options, &block) Link segment, styled like a button segment.
t.remove(url = nil, **options, &block) Trailing remove segment: a link when +url+ is given, otherwise a
button. Renders a ✕ icon unless the block supplies custom content.
t.popover(id: nil, placement: :bottom, align: :start, open: false, &block)
Attaches a popover to the tag; the block is the popover body.
Options match +l_ui_popover+.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'app/helpers/layered/ui/tag_helper.rb', line 48 def l_ui_tag(rounded: false, container: {}, &block) builder = TagBuilder.new(self) capture { block.call(builder) } container_attrs = container.deep_dup container_attrs[:class] = class_names("l-ui-tag", ("l-ui-tag--rounded" if rounded), container_attrs[:class]) if builder.popover? 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-target"] = "trigger" container_data[:"l-ui--popover-placement-value"] = builder.popover_placement container_data[:"l-ui--popover-align-value"] = builder.popover_align container_data[:"l-ui--popover-open-value"] = true if builder.popover_open container_attrs[:data] = container_data end tag.div(**container_attrs) do parts = builder.segments.map { |segment| l_ui_tag_segment(builder, segment) } parts << l_ui_tag_popover(builder) if builder.popover? safe_join(parts) end end |