module Coco module ComponentsHelper include ActionView::Helpers::UrlHelper # Buttons def coco_button(*args, **kwargs, &block) href, content = if block [args.first, nil] else (args.size == 1) ? [nil, args.first] : args[0..2].reverse! end button = if kwargs.key?(:action) || kwargs.key?(:method) || kwargs.key?(:params) "Coco::ButtonTo" else "Coco::Button" end component = button.constantize.new(href: href, **kwargs) component = component.with_content(content) if !block && content.present? render(component, &block) end def coco_button_group(**, &) render(Coco::ButtonGroup.new(**), &) end def coco_menu_button(**, &) render(Coco::MenuButton.new(**), &) end def coco_menu_item(type, **, &) render(coco_component("menu_items/#{type}", **), &) end def coco_confirm_button(href = nil, **, &) render(Coco::ConfirmButton.new(href: href, **), &) end def coco_color_picker_button(**, &) render(Coco::ColorPickerButton.new(**), &) end def coco_image_picker_button(**, &) render(Coco::ImagePickerButton.new(**), &) end def coco_layout_picker_button(**, &) render(Coco::LayoutPickerButton.new(**), &) end def coco_toolbar(**, &) render(Coco::Toolbar.new(**), &) end def coco_option_bar(**, &) render(Coco::OptionBar.new(**), &) end # Embeds def coco_embed(platform, url = nil, **) case platform when :youtube render Coco::YoutubeEmbed.new(url: url, **) else raise ArgumentError, "`#{platform}` is not a valid embed type" end end # Forms (WIP) def coco_form_with(**, &) form_with(**, builder: Coco::AppFormBuilder, &) end def coco_form_for(*, **, &) form_for(*, **, builder: Coco::AppFormBuilder, &) end def coco_fields(**, &) fields(**, builder: Coco::AppFormBuilder, &) end # Images def coco_svg(path = nil, **) render Coco::Svg.new(path: path, **) end def coco_image(src = nil, **) render Coco::Image.new(src: src, **) end def coco_avatar(src, name = nil, **) render Coco::Avatar.new(src: src, name: name, **) end def coco_icon(icon_name = nil, **, &) render(Coco::Icon.new(name: icon_name, **), &) end # Indicators def coco_stamp(type = nil, **) props = case type when :success, :positive {icon: :check_circle, theme: :positive} when :error, :negative {icon: :alert_circle, theme: :negative} when :warning {icon: :alert_triangle, theme: :warning} when :info {icon: :info, theme: :info} else {} end render Coco::Stamp.new(**props, **) end def coco_badge(text, **) render Coco::Badge.new(**).with_content(text) end # Layout def coco_spacer(size = Coco::Spacer::DEFAULT, **) render Coco::Spacer.new(size:, **) end alias_method :space, :coco_spacer def coco_stack(spacing: Coco::Spacer::DEFAULT, **, &) render(Coco::Stack.new(spacing:, **), &) end def coco_panel(**, &) render(Coco::Panel.new(**), &) end def coco_page(id, **, &) render(Coco::Page.new(id: id, **), &) end # Messaging def coco_notice(**, &) render(Coco::Notice.new(**), &) end def coco_snackbar(**, &) render(Coco::Snackbar.new(**), &) end def coco_toast(**, &) render(Coco::Toast.new(**), &) end def coco_system_banner(**, &) render(Coco::SystemBanner.new(**), &) end # Modals def coco_modal(name = "default", **, &) render(Coco::Modal.new(name: name, **), &) end def coco_modal_dialog(name = "default", **, &block) render(Coco::Modal.new(name: name, **)) do |modal| modal.with_container_dialog(&block) end end def coco_modal_lightbox(name = "default", scroll_top: nil, **, &block) render(Coco::Modal.new(name: name, scroll_top: scroll_top, **)) do |modal| modal.with_container_lightbox(&block) end end # Navigation def coco_link(*args, **, &block) href, content = if block [args.first, nil] else (args.size == 1) ? [nil, args.first] : args[0..2].reverse! end link = Coco::Link.new(href: href, **) link = link.with_content(content) if !block && content.present? render(link, &block) end def coco_link_to(name = nil, options = nil, html_options = nil, &block) html_options, options, name = options, name, block if block options ||= {} html_options = Coco::ActionViewHelper.convert_options_to_data_attributes(options, html_options) href = Coco::ActionViewHelper.url_target(name, options) if block coco_link(href, **html_options.symbolize_keys!, &block) else coco_link(name, href, **html_options.symbolize_keys!) end end def coco_button_to(name = nil, options = nil, html_options = nil, &block) html_options, options = options, name if block options ||= {} html_options ||= {} html_options.symbolize_keys! button = Coco::ButtonTo.new(action: options, type: :submit, **html_options) button = button.with_content(name) unless block render(button, &block) end def coco_pager_button(direction, **, &) render(Coco::PagerButton.new(direction:, **), &) end # Typography def coco_prose(**, &) render(Coco::Prose.new(**), &) end def coco_seamless_textarea(**, &) render(Coco::SeamlessTextarea.new(**), &) end # Utilties (internal) def coco_placeholder(text_content = nil, **, &) render(Coco::Placeholder.new(text_content:, **), &) end # General def coco_tag(*, **, &) render(Coco::Tag.new(*, **), &) end def coco_component(name, *, **) resolve_component("coco/#{name}", *, **) end def resolve_component(...) Coco::ComponentResolver.new(...) end end end