Class: NitroKit::Table
- Defined in:
- app/components/nitro_kit/table.rb
Defined Under Namespace
Constant Summary collapse
- ALIGNMENTS =
%i[left center right].freeze
- DEFAULT_ALIGNMENT =
:left- SCOPES =
%i[col row].freeze
- DIRECTIONS =
%i[asc desc].freeze
- SORT_ICONS =
{ asc: "arrow-up", desc: "arrow-down", none: "chevrons-up-down" }.freeze
Constants inherited from Component
Component::ADDITIVE_DATA_ATTRIBUTES, Component::COMPONENT_OWNED_DATA_ATTRIBUTES, Component::FORBIDDEN_ATTRIBUTES, Component::RESERVED_DATA_ATTRIBUTES
Instance Attribute Summary collapse
-
#direction ⇒ Object
readonly
Returns the value of attribute direction.
-
#sort ⇒ Object
readonly
Returns the value of attribute sort.
Instance Method Summary collapse
- #caption(text = nil, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
- #html_caption ⇒ Object
- #html_tbody ⇒ Object
- #html_td ⇒ Object
- #html_th ⇒ Object
- #html_thead ⇒ Object
- #html_tr ⇒ Object
-
#initialize(sort: nil, direction: nil, id: nil, html: {}, aria: {}, data: {}, table_html: {}, table_aria: {}, table_data: {}, desperately_need_a_class: nil) ⇒ Table
constructor
Table renders in two phases.
- #tbody(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
- #td(text = nil, align: :left, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
- #th(text = nil, align: :left, scope: :col, sort: nil, href: nil, sort_data: {}, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
- #thead(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
- #tr(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
- #view_template ⇒ Object
Constructor Details
#initialize(sort: nil, direction: nil, id: nil, html: {}, aria: {}, data: {}, table_html: {}, table_aria: {}, table_data: {}, desperately_need_a_class: nil) ⇒ Table
Table renders in two phases. caption, thead, and tbody only collect
declarations, so the component owns caption → head → body order regardless
of caller order. tr, th, and td run inside a collected block and
render immediately, which is why their validation raises before the cell
it describes is emitted rather than after the table is complete.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'app/components/nitro_kit/table.rb', line 18 def initialize( sort: nil, direction: nil, id: nil, html: {}, aria: {}, data: {}, table_html: {}, table_aria: {}, table_data: {}, desperately_need_a_class: nil ) @sort = sort.nil? ? nil : normalize_sort_key(sort, name: "sort") @direction = direction.nil? ? nil : validate_choice!(:direction, direction.to_sym, DIRECTIONS) unless @sort.nil? == @direction.nil? raise ArgumentError, "Table sort: and direction: must both be set or both be nil" end super( component: :table, attributes: { id:, data: { sort: @sort, direction: @direction }.compact }.compact, html:, aria:, data:, desperately_need_a_class: ) @table_attributes = slot_attributes( :element, html: table_html, aria: table_aria, data: table_data ) @caption = nil @head = nil @bodies = [] @sort_keys = [] end |
Instance Attribute Details
#direction ⇒ Object (readonly)
Returns the value of attribute direction.
57 58 59 |
# File 'app/components/nitro_kit/table.rb', line 57 def direction @direction end |
#sort ⇒ Object (readonly)
Returns the value of attribute sort.
57 58 59 |
# File 'app/components/nitro_kit/table.rb', line 57 def sort @sort end |
Instance Method Details
#caption(text = nil, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/components/nitro_kit/table.rb', line 82 def caption(text = nil, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ensure_collecting_sections!(:caption) raise ArgumentError, "Table accepts at most one caption" if @caption raise ArgumentError, "Table caption accepts text or a block, not both" if !text.nil? && block validate_content_text!("Table caption", text) unless block @caption = Caption.new( text:, content: block, html:, aria:, data:, css_class: desperately_need_a_class ) nil end |
#html_caption ⇒ Object
75 |
# File 'app/components/nitro_kit/table.rb', line 75 alias :html_caption :caption |
#html_tbody ⇒ Object
77 |
# File 'app/components/nitro_kit/table.rb', line 77 alias :html_tbody :tbody |
#html_td ⇒ Object
80 |
# File 'app/components/nitro_kit/table.rb', line 80 alias :html_td :td |
#html_th ⇒ Object
79 |
# File 'app/components/nitro_kit/table.rb', line 79 alias :html_th :th |
#html_thead ⇒ Object
76 |
# File 'app/components/nitro_kit/table.rb', line 76 alias :html_thead :thead |
#html_tr ⇒ Object
78 |
# File 'app/components/nitro_kit/table.rb', line 78 alias :html_tr :tr |
#tbody(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
108 109 110 111 112 113 114 |
# File 'app/components/nitro_kit/table.rb', line 108 def tbody(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ensure_collecting_sections!(:tbody) raise ArgumentError, "Table tbody requires a block" unless block @bodies << Section.new(content: block, html:, aria:, data:, css_class: desperately_need_a_class) nil end |
#td(text = nil, align: :left, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'app/components/nitro_kit/table.rb', line 170 def td( text = nil, align: :left, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block ) ensure_rendering_row!(:td) raise ArgumentError, "Table td accepts text or a block, not both" if !text.nil? && block alignment = validate_choice!(:align, align, ALIGNMENTS) html_td( **slot_attributes( :cell, attributes: { data: { align: alignment_value(alignment) }.compact }, html:, aria:, data:, desperately_need_a_class: ) ) { text_or_block(text, &block) } end |
#th(text = nil, align: :left, scope: :col, sort: nil, href: nil, sort_data: {}, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'app/components/nitro_kit/table.rb', line 128 def th( text = nil, align: :left, scope: :col, sort: nil, href: nil, sort_data: {}, html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block ) ensure_rendering_row!(:th) raise ArgumentError, "Table th accepts text or a block, not both" if !text.nil? && block raise ArgumentError, "Table th href: requires sort:" if sort.nil? && !href.nil? alignment = validate_choice!(:align, align, ALIGNMENTS) scope = validate_choice!(:scope, scope, SCOPES) key = sort.nil? ? nil : declare_sort_header!(sort, href:) html_th( **slot_attributes( :header, attributes: { scope:, aria: key ? { sort: aria_sort(key) } : {}, data: { align: alignment_value(alignment), sort_key: key }.compact }, html:, aria:, data:, desperately_need_a_class: ) ) do if key render_sort_link(key, text, href:, data: sort_data, &block) else text_or_block(text, &block) end end end |
#thead(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
99 100 101 102 103 104 105 106 |
# File 'app/components/nitro_kit/table.rb', line 99 def thead(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ensure_collecting_sections!(:thead) raise ArgumentError, "Table accepts at most one thead" if @head raise ArgumentError, "Table thead requires a block" unless block @head = Section.new(content: block, html:, aria:, data:, css_class: desperately_need_a_class) nil end |
#tr(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 |
# File 'app/components/nitro_kit/table.rb', line 116 def tr(html: {}, aria: {}, data: {}, desperately_need_a_class: nil, &block) raise ArgumentError, "Table rows must be declared inside thead or tbody" unless @rendering_section raise ArgumentError, "Table tr requires a block" unless block html_tr(**slot_attributes(:row, html:, aria:, data:, desperately_need_a_class:)) do @rendering_row = true render(block) ensure @rendering_row = false end end |
#view_template ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'app/components/nitro_kit/table.rb', line 59 def view_template @collecting_sections = true yield self if block_given? @collecting_sections = false div(**root_attributes) do table(**@table_attributes) do render_caption if @caption render_section(:head, @head, :html_thead) if @head @bodies.each { |body| render_section(:body, body, :html_tbody) } end end ensure @collecting_sections = false end |