# frozen_string_literal: true module Ariadne # Add a general description of component here # Add additional usage considerations or best practices that may aid the user to use the component correctly. # @accessibility Add any accessibility considerations class TableComponent < Ariadne::Component DEFAULT_CLASSES = "ariadne-min-w-full ariadne-divide-y ariadne-divide-gray-300 flex flex-col" renders_one :header_row, "HeaderRowItem" renders_many :rows, "RowItem" renders_one :footer, "FooterItem" # @example Default # # <%= render(Ariadne::TableComponent.new) do |table| %> # <%= table.header_row do |header_row| %> # <% header_row.cell do %> # State # <% end %> # <% end %> # <%= table.row do |row| %> # <% row.cell do %> # "California" # <% end %> # <% end %> # <%= table.row do |row| %> # <% row.cell do %> # "New York" # <% end %> # <% end %> # <%= table.row do |row| %> # <% row.cell do %> # "Texas" # <% end %> # <% end %> # <% end %> # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> def initialize(classes: "", attributes: {}) @tag = :div @classes = class_names( DEFAULT_CLASSES, classes, ) @attributes = attributes end def has_header_row? header_row.present? end def has_footer? footer.present? end # This component is part of `TableComponent` and should not be # used as a standalone component. class RowItem < Ariadne::Component DEFAULT_ROW_CLASSES = "ariadne-whitespace-nowrap ariadne-py-4 ariadne-pl-4 ariadne-pr-3 ariadne-text-sm sm:ariadne-pl-6 flex flex-row" renders_many :cells, lambda { |classes: "", attributes: {}| if @header Ariadne::TableComponent::RowItem::HeaderCellItem.new(classes: classes, attributes: attributes) else Ariadne::TableComponent::RowItem::CellItem.new(classes: classes, attributes: attributes) end } # @param link [Hash] #TODO: link attributes def initialize(link: "", classes: "", attributes: {}) @header = false @link = link @classes = if @link.present? class_names( DEFAULT_ROW_CLASSES, "ariadne-cursor-pointer", classes, ) else class_names( DEFAULT_ROW_CLASSES, classes, ) end @attributes = attributes end def call render(Ariadne::BaseComponent.new(tag: :li, classes: @classes, attributes: @attributes)) do if linked? render(Ariadne::LinkComponent.new(href: @link[:href], classes: @link[:classes], attributes: @link[:attributes])) do cells.each do |cell| concat(cell) end end else cells.each do |cell| concat(cell) end end end end private def linked? @link.present? end # This component is part of `TableComponent` and should not be # used as a standalone component. class HeaderCellItem < Ariadne::TableComponent::RowItem DEFAULT_HEADER_CELL_CLASSES = "ariadne-py-3.5 ariadne-pl-4 pr-3 ariadne-text-left ariadne-text-sm ariadne-font-semibold ariadne-text-gray-900 ariadne-sm:pl-6" def initialize(classes: "", attributes: {}) @classes = class_names( DEFAULT_HEADER_CELL_CLASSES, classes, ) @attributes = attributes end def call render(Ariadne::BaseComponent.new(tag: :span, classes: @classes, attributes: @attributes)) { content } end end # This component is part of `TableComponent` and should not be # used as a standalone component. class CellItem < Ariadne::TableComponent::RowItem DEFAULT_CELL_CLASSES = "" def initialize(classes: "", attributes: {}) @classes = class_names( DEFAULT_CELL_CLASSES, classes, ) @attributes = attributes end def call render(Ariadne::BaseComponent.new(tag: :span, classes: @classes, attributes: @attributes)) { content } end end end # This component is part of `TableComponent` and should not be # used as a standalone component. class HeaderRowItem < Ariadne::TableComponent::RowItem DEFAULT_HEADER_CLASSES = "ariadne-bg-gray-50 flex flex-row" def initialize(classes: "", attributes: {}) @header = true @classes = class_names( DEFAULT_HEADER_CLASSES, classes, ) @attributes = attributes end def call render(Ariadne::BaseComponent.new(tag: :div, classes: @classes, attributes: @attributes)) do cells.each do |cell| concat(cell) end end end end # This component is part of `TableComponent` and should not be # used as a standalone component. class FooterItem < Ariadne::Component DEFAULT_CLASSES = "ariadne-border-none ariadne-flex ariadne-items-center ariadne-justify-between ariadne-px-4 ariadne-py-3 sm:ariadne-px-6" DEFAULT_RESULT_CLASSES = "ariadne-text-sm ariadne-text-gray-700" renders_one :records_info, lambda { |classes: "", attributes: {}| actual_classes = class_names(DEFAULT_RESULT_CLASSES, classes) Ariadne::BaseComponent.new(tag: :p, classes: actual_classes, attributes: attributes) } renders_one :pagination_bar, "Ariadne::TableComponent::PaginationBarItem" def initialize(classes: "", attributes: {}) @classes = class_names( DEFAULT_CLASSES, classes, ) @attributes = attributes end def call render(Ariadne::BaseComponent.new(tag: :div, classes: @classes, attributes: @attributes)) do records_info.to_s + pagination_bar.to_s end end end # This component is part of `TableComponent` and should not be # used as a standalone component. class PaginationBarItem < Ariadne::Component DEFAULT_PREV_PAGE_CLASSES = "ariadne-relative ariadne-inline-flex ariadne-items-center ariadne-rounded-l-md ariadne-border ariadne-border-gray-300 ariadne-bg-white ariadne-px-2 ariadne-py-2 ariadne-text-sm ariadne-font-medium ariadne-text-gray-500 focus:ariadne-z-20" renders_one :prev_page, lambda { |disabled: false, href:, classes: "", attributes: {}| if disabled actual_classes = class_names(DEFAULT_PREV_PAGE_CLASSES, classes) render(Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)) do render(Ariadne::HeroiconComponent.new(icon: "chevron-left", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only")) end else actual_classes = class_names(DEFAULT_PREV_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes) attributes[:"aria-label"] = "previous" render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) do render(Ariadne::HeroiconComponent.new(icon: "chevron-left", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only")) end end } renders_one :page_list, lambda { |disabled: false, href:, classes: "", attributes: {}| if disabled actual_classes = class_names(DEFAULT_NEXT_PAGE_CLASSES, classes) render(Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)) do render(Ariadne::HeroiconComponent.new(icon: "chevron-left", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only")) end else actual_classes = class_names(DEFAULT_NEXT_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes) attributes[:"aria-label"] = "next" render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) do render(Ariadne::HeroiconComponent.new(icon: "chevron-right", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only")) end end } DEFAULT_NEXT_PAGE_CLASSES = " ariadne-relative ariadne-inline-flex ariadne-items-center ariadne-rounded-r-md ariadne-border ariadne-border-gray-300 ariadne-bg-white ariadne-px-2 ariadne-py-2 ariadne-text-sm ariadne-font-medium ariadne-text-gray-500 focus:ariadne-z-20" renders_one :next_page, lambda { |disabled: false, href:, classes: "", attributes: {}| if disabled actual_classes = class_names(DEFAULT_NEXT_PAGE_CLASSES, classes) render(Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)) do render(Ariadne::HeroiconComponent.new(icon: "chevron-left", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only")) end else actual_classes = class_names(DEFAULT_NEXT_PAGE_CLASSES, "hover:ariadne-bg-gray-50", classes) attributes[:"aria-label"] = "next" render(Ariadne::LinkComponent.new(href: href, classes: actual_classes, attributes: attributes)) do render(Ariadne::HeroiconComponent.new(icon: "chevron-right", size: :sm, variant: :mini, text_attributes: { "aria-hidden": true }, text_classes: "ariadne-sr-only")) end end } DEFAULT_PAGINATOR_CLASSES = "ariadne-flex ariadne-items-center ariadne-justify-between ariadne-m-10" def initialize(classes: "", attributes: {}) @classes = class_names( DEFAULT_PAGINATOR_CLASSES, classes, ) @attributes = attributes @attributes[:"aria-label"] ||= "paginator" end def call render(Ariadne::BaseComponent.new(tag: :nav, classes: @classes, attributes: @attributes)) do prev_page.to_s + next_page.to_s end end end end end