# typed: false # frozen_string_literal: true module Ariadne module UI module Popover class Component < Ariadne::BaseComponent ALIGNMENT_DEFAULT = :center ALIGNMENT_OPTIONS = [:left, :right, ALIGNMENT_DEFAULT] POSITION_DEFAULT = :auto POSITION_OPTIONS = [POSITION_DEFAULT, :above, :below] option :target_id, optional: true option :position, default: proc { POSITION_DEFAULT } option :alignment, default: proc { ALIGNMENT_DEFAULT } renders_one :button, lambda { |**options| options[:html_attrs] ||= {} options[:html_attrs] = { popovertarget: target_id, popovertargetaction: "toggle", }.merge(options[:html_attrs]) # requires CSS Anchor Positioning # options[:html_attrs][:style] = "anchor-name: --popover-#{target_id};" options[:html_attrs][:data] ||= {} options[:html_attrs][:data] = { "#{stimulus_name}-target" => ["toggle", html_attrs.fetch(:data, {}).fetch(:target, nil)].compact.join(" "), }.merge(options[:html_attrs][:data]) Ariadne::UI::Button::Component.new(**options) } accepts_html_attributes do |html_attrs| html_attrs[:id] ||= target_id html_attrs[:popover] = "" # requires CSS Anchor Positioning # as a `style` to account for future feature where the popover can be moved # html_attrs[:style] = "inset: unset; top: anchor(--popover-#{target_id} bottom); right: anchor(--popover-#{target_id} left, -1rem);" @stimulus_controllers = [stimulus_name, html_attrs.fetch(:data, {}).delete(:controller)].compact.join(" ") html_attrs[:data] ||= {} html_attrs[:data] = { "#{stimulus_name}-target" => ["popover", html_attrs.fetch(:data, {}).fetch(:target, nil)].compact.join(" "), "#{stimulus_name}-placement-value" => popover_placement, }.merge(html_attrs[:data]) end def popover_placement placement = case @position when :above then "top" when :below then "bottom" else "bottom" end placement += "-start" if @alignment == :left placement += "-end" if @alignment == :right placement end def target_id @target_id ||= Ariadne.generate_id end style do base do [ "ariadne-fixed", "ariadne-z-20", "ariadne-rounded-lg", "ariadne-shadow-lg", "ariadne-bg-foreground", "dark:ariadne-bg-foreground-dark", ] end end end end end end