Sha256: eb26506f8eb5164466eef2fa55343792f3e1d897278dc63cb2603bb67c320a44

Contents?: true

Size: 1.98 KB

Versions: 42

Compression:

Stored size: 1.98 KB

Contents

# typed: false
# frozen_string_literal: true

require "action_view/helpers/tag_helper"

module Ariadne
  module ViewComponent
    module HTMLAttrs
      class AttributesHash < ::Hash
        TAG_BUILDER = ActionView::Helpers::TagHelper::TagBuilder.new(nil)
        TAG_OPTIONS = ActionView::Helpers::TagHelper::TagBuilder.instance_method(:tag_options)

        def to_html(nested: false)
          # TODO: implement + change usage by @tag nested-attributes
          tag_options(self)&.html_safe # rubocop:disable Rails/OutputSafety
        end
        private def tag_options(...) = TAG_OPTIONS.bind_call(TAG_BUILDER, ...)
      end

      extend ActiveSupport::Concern

      class_methods do
        def accepts_html_attributes_for(name, **defaults, &block)
          html_attribute_accessors[name] = defaults

          name = name.to_sym
          method_name = :"#{name}_attrs"
          ivar_name = :"@#{method_name}"

          attr_reader(method_name)

          mod = Module.new do
            define_method(:initialize) do |**options|
              value = self.class.default_html_attributes_for(name).deep_merge!(options.delete(method_name).to_h)
              super(**options)
              instance_exec(value, &block) if block
              instance_variable_set(ivar_name, value)
            end
          end

          prepend(mod)
        end

        def accepts_html_attributes(**defaults, &block)
          accepts_html_attributes_for(:html, **defaults, &block)
        end

        def html_attribute_accessors
          @html_attribute_accessors ||=
            if superclass.respond_to?(:html_attribute_accessors)
              superclass.html_attribute_accessors.deep_dup
            else
              {}
            end
        end

        def default_html_attributes_for(name)
          html_attribute_accessors.fetch(name).each_with_object(AttributesHash.new) do |(k, v), acc|
            acc[k] = v.is_a?(Proc) ? v.call : v
            acc
          end
        end
      end
    end
  end
end

Version data entries

42 entries across 42 versions & 1 rubygems

Version Path
ariadne_view_components-0.0.69 app/lib/ariadne/view_component/html_attrs.rb
ariadne_view_components-0.0.68 app/lib/ariadne/view_component/html_attrs.rb