module Coco module App module Blocks class SlideEditor < Coco::Component include Coco::AppHelper include Coco::BookHelper include Coco::FormatHelper renders_one :bg_color, ->(name: :bg_color_hex, **input_options) do add_field(:bg_color, name, input_options) end renders_one :text_color, ->(name: :text_color_hex, **input_options) do add_field(:text_color, name, input_options) end renders_one :bg_image, ->(name: :bg_image, **input_options) do add_field(:bg_image, name, input_options) end renders_one :thumbnail, ->(name: :thumbnail_image, **input_options) do add_field(:thumbnail, name, input_options) end renders_one :title, ->(name: :title, **input_options) do add_field(:title, name, input_options) end renders_one :text_1, ->(name: :text_1, **input_options) do add_field(:text_1, name, input_options) end renders_one :layout, ->(name: :layout, **input_options) do add_field(:layout, name, input_options) end before_render do with_layout(value: "basic") unless layout? end attr_reader :fields def initialize(form: nil, **kwargs) @form_args = form.to_h @model = @form_args[:model] @fields = {} end def form_args(attrs = {}) html_args = @form_args.fetch(:html, {}) attrs[:class] = class_names(html_args[:class], attrs[:class]) html_args.merge!(attrs) @form_args.merge({html: html_args}) end def slide_args { bg_image: bg_image_value, bg_color_hex: bg_color_value, text_color_hex: text_color_value, layout: layout_value, render_empty: true } end def alpine_props { bg_color: format_css_hex_color(bg_color_value), text_color: format_css_hex_color(text_color_value), title: title_value, text_1: text_1_value, layout: layout_value, bg_image: { name: ((field?(:bg_image) && bg_image_value.present?) && File.basename(bg_image_value)), data: (bg_image_value if field?(:bg_image)) } } end def method_missing(name, *args, &block) name.match(/_(value|options|name)/) do |matches| field_name = name.to_s.gsub(matches[0], "").to_sym method = matches[1].to_sym if field?(field_name) fields[field_name].public_send(method) end end end def respond_to_missing?(name, include_private = false) field_name = name.to_s.gsub(/_(value|options|name)/, "") field?(field_name.to_sym) end def field?(name) fields.key?(name) end private def add_field(field_name, name, options = {}) model_value = @model&.public_send(name) if @model&.respond_to?(name) fields[field_name] = SlideInput.new(name, model_value, options) end SlideInput = Data.define(:name, :model_value, :input_options) do def value input_options.fetch(:value, model_value) end def options input_options.tap do |options| options[:value] = value end end def to_json "\"#{value}\"" if value.present? end alias_method :to_s, :value end end end end end