# frozen_string_literal: true
require "html_attributes_utils"
module Katalyst
module Tables
# Adds HTML attributes to a component.
# Accepts HTML attributes from the constructor or via `html_attributes=`.
# These are merged with the default attributes defined in the component.
# Adds support for custom html attributes for other tags, e.g.:
# define_html_attribute_methods :table_attributes, default: {}
# tag.table(**table_attributes)
module HasHtmlAttributes
extend ActiveSupport::Concern
using HTMLAttributesUtils
MERGEABLE_ATTRIBUTES = [
*HTMLAttributesUtils::DEFAULT_MERGEABLE_ATTRIBUTES,
%i[data controller],
%i[data action],
].freeze
refine Hash do
def merge_html(attributes)
deep_merge_html_attributes(attributes, mergeable_attributes: MERGEABLE_ATTRIBUTES)
end
end
class_methods do
using HasHtmlAttributes
def define_html_attribute_methods(name, default: {})
define_method("default_#{name}") { default }
private("default_#{name}")
define_method(name) do
send("default_#{name}").merge_html(instance_variable_get("@#{name}") || {})
end
define_method("#{name}=") do |options|
instance_variable_set("@#{name}", options.slice(:id, :aria, :class, :data).merge(options.fetch(:html, {})))
end
end
end
included do
define_html_attribute_methods :html_attributes, default: {}
# Backwards compatibility with tables 1.0
alias_method :options, :html_attributes=
end
def initialize(**options)
super(**options.except(:id, :aria, :class, :data, :html))
self.html_attributes = options
end
end
end
end