phlexi-table 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/phlexi/table/base.rb +356 -74
  3. data/lib/phlexi/table/components/actions_column.rb +43 -0
  4. data/lib/phlexi/table/components/base.rb +22 -18
  5. data/lib/phlexi/table/components/column.rb +14 -0
  6. data/lib/phlexi/table/components/column_group.rb +23 -0
  7. data/lib/phlexi/table/components/concerns/displays_data.rb +27 -0
  8. data/lib/phlexi/table/components/concerns/displays_header.rb +30 -0
  9. data/lib/phlexi/table/components/concerns/groups_columns.rb +36 -0
  10. data/lib/phlexi/table/components/data_column.rb +33 -0
  11. data/lib/phlexi/table/components/header_cell.rb +19 -0
  12. data/lib/phlexi/table/components/options/alignment.rb +31 -0
  13. data/lib/phlexi/table/components/options/labels.rb +30 -0
  14. data/lib/phlexi/table/components/selection_cell.rb +17 -0
  15. data/lib/phlexi/table/components/selection_column.rb +21 -0
  16. data/lib/phlexi/table/components/sortable_header_cell.rb +74 -0
  17. data/lib/phlexi/table/display_theme.rb +6 -0
  18. data/lib/phlexi/table/html.rb +15 -0
  19. data/lib/phlexi/table/options/captions.rb +22 -0
  20. data/lib/phlexi/table/{field_options/description.rb → options/descriptions.rb} +5 -5
  21. data/lib/phlexi/table/theme.rb +25 -0
  22. data/lib/phlexi/table/version.rb +1 -1
  23. data/lib/phlexi/table/wrapped_object.rb +27 -0
  24. data/lib/phlexi/table.rb +5 -6
  25. metadata +49 -25
  26. data/lib/phlexi/table/components/concerns/displays_value.rb +0 -54
  27. data/lib/phlexi/table/components/date_time.rb +0 -49
  28. data/lib/phlexi/table/components/description.rb +0 -21
  29. data/lib/phlexi/table/components/hint.rb +0 -21
  30. data/lib/phlexi/table/components/label.rb +0 -15
  31. data/lib/phlexi/table/components/number.rb +0 -37
  32. data/lib/phlexi/table/components/placeholder.rb +0 -15
  33. data/lib/phlexi/table/components/string.rb +0 -17
  34. data/lib/phlexi/table/components/wrapper.rb +0 -17
  35. data/lib/phlexi/table/field_options/associations.rb +0 -21
  36. data/lib/phlexi/table/field_options/attachments.rb +0 -21
  37. data/lib/phlexi/table/field_options/hints.rb +0 -22
  38. data/lib/phlexi/table/field_options/inferred_types.rb +0 -129
  39. data/lib/phlexi/table/field_options/labels.rb +0 -28
  40. data/lib/phlexi/table/field_options/placeholders.rb +0 -18
  41. data/lib/phlexi/table/field_options/themes.rb +0 -132
  42. data/lib/phlexi/table/structure/dom.rb +0 -42
  43. data/lib/phlexi/table/structure/field_builder.rb +0 -158
  44. data/lib/phlexi/table/structure/field_collection.rb +0 -39
  45. data/lib/phlexi/table/structure/namespace.rb +0 -123
  46. data/lib/phlexi/table/structure/namespace_collection.rb +0 -40
  47. data/lib/phlexi/table/structure/node.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e05e322aef835f61e4d9c75e678c54ed3abd96675b7eaedb7db6b8138f826450
4
- data.tar.gz: 3d2e8b90865ab5e8e5b5b405046277a51177508187f3fde2d708612bed01dc6f
3
+ metadata.gz: ea441f5dc6bff0752e14011507ba3274026a46f8900de536f7b1d253fff45c44
4
+ data.tar.gz: 05dd06af33197b2f8847d2bfab878340cf23d28d9c824b53382497343ae1de13
5
5
  SHA512:
6
- metadata.gz: e9e99ffd0dff1b5e92cdc779c8cd3fd5dee46e20094916e50eeec337c1af2b88fd0b9fa637dd56f54ad3a12381e0d2b2434747d536a4bb5fff928d08ccd6dd1f
7
- data.tar.gz: 4f97e0de92ea6e09b17d7e09c6d242ee968638c6d4766991515aa54d3e738a51219190ca4d1fd944205b06b627eb9c3a2b0e7125adf5cb22eda839f14a5c7668
6
+ metadata.gz: 5db97df1ef5cf3131212ee6ce6a9b043dffd5d97f68e783ceca071b95cbedbb3a7a57086d82d0285cd100714e6aa0994001615f99768a56154cd4296df2eac75
7
+ data.tar.gz: 48935e08c5e0dfb4b9fb110ebe7a14cffc5d3a73930a0ad7779e89fbe3579c4a19ebe72062deaac07df84b8a47fe73351ee7a0e8555bdadf79c01e02ba72d9df
@@ -1,118 +1,400 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/module/delegation"
4
- require "active_support/core_ext/string/inflections"
5
-
6
3
  module Phlexi
7
4
  module Table
8
- # A display component for rendering flexible and customizable data views.
5
+ # Base class for creating customizable table components
9
6
  #
10
7
  # @example Basic usage
11
- # Phlexi::Table.new(user) do |d|
12
- # render d.field(:name).text
13
- # render d.field(:email).text
8
+ # class UsersTable < Phlexi::Table::Base
9
+ # def table_template
10
+ # table_caption "Caption"
11
+ # table_description "Description"
12
+ # selection_column :id
13
+ # column :name
14
+ # column :a_sorted_column, sort_params: {url: "url", reset_url: "reset_url", position: "multisort position", direction: "ASC|DESC"}
15
+ # column_group :a_grouped_column do |g|
16
+ # g.column :sub_col1
17
+ # g.column :sub_col2
18
+ # end
19
+ # actions do |user|
20
+ # link_to "Edit", edit_user_path(user)
21
+ # end
22
+ # end
14
23
  # end
15
24
  #
16
- # @attr_reader [Symbol] key The display's key, derived from the record or explicitly set
17
- # @attr_reader [ActiveModel::Model, nil] object The display's associated object
18
- class Base < COMPONENT_BASE
19
- class Namespace < Structure::Namespace; end
20
-
21
- class FieldBuilder < Structure::FieldBuilder; end
22
-
23
- attr_reader :key, :object
24
-
25
- delegate :field, :nest_one, :nest_many, to: :@namespace
26
-
27
- # Initializes a new Table instance.
28
- #
29
- # @param record [ActiveModel::Model, Symbol, String] The display's associated record or key
30
- # @param attributes [Hash] Additional HTML attributes for the display container
31
- # @param options [Hash] Additional options for display configuration
32
- # @option options [String] :class CSS classes for the display
33
- # @option options [Class] :namespace_klass Custom namespace class
34
- # @option options [Class] :builder_klass Custom field builder class
35
- def initialize(record, attributes: {}, **options)
36
- @display_class = options.delete(:class)
37
- @attributes = attributes
38
- @namespace_klass = options.delete(:namespace_klass) || default_namespace_klass
39
- @builder_klass = options.delete(:builder_klass) || default_builder_klass
25
+ # render UsersTable.new(User.all)
26
+ #
27
+ # @attr_reader [Enumerable] collection The collection of items to display in the table
28
+ # @attr_reader [Hash] columns The columns defined for the table
29
+ class Base < Phlexi::Table::HTML
30
+ include Phlex::DeferredRender
31
+ include Phlexi::Table::Options::Captions
32
+ include Phlexi::Table::Options::Descriptions
33
+
34
+ class DataColumn < Phlexi::Table::Components::DataColumn; end
35
+
36
+ class SelectionColumn < Phlexi::Table::Components::SelectionColumn; end
37
+
38
+ class ActionsColumn < Phlexi::Table::Components::ActionsColumn; end
39
+
40
+ class ColumnGroup < Phlexi::Table::Components::ColumnGroup; end
41
+
42
+ class Display < Phlexi::Display::Base; end
43
+
44
+ attr_reader :key, :collection, :columns, :options
45
+
46
+ # Initialize a new table component
47
+ #
48
+ # @param collection [Enumerable] The collection of items to display
49
+ # @param options [Hash] Additional options for customizing the table
50
+ # @option options [String] :id The ID attribute for the table
51
+ # @option options [String] :class The CSS class(es) for the table
52
+ # @raise [ArgumentError] If the collection is empty
53
+ def initialize(collection, **options)
54
+ @collection = Array(collection)
55
+ raise ArgumentError, "Collection cannot be empty" if @collection.empty?
56
+
57
+ @columns = {}
40
58
  @options = options
59
+ initialize_key
60
+ end
41
61
 
42
- initialize_object_and_key(record)
43
- initialize_namespace
62
+ def around_template
63
+ original_template = Phlexi::Display::Theme.instance
64
+ Phlexi::Display::Theme.instance = Phlexi::Table::DisplayTheme.instance
65
+ super
66
+ ensure
67
+ Phlexi::Display::Theme.instance = original_template
68
+ end
69
+
70
+ def before_template
71
+ super
72
+ table_template
44
73
  end
45
74
 
46
- # Renders the display template.
47
- #
48
- # @return [void]
49
75
  def view_template
50
- display_template
76
+ render_table
51
77
  end
52
78
 
53
- # Executes the display's content block.
54
- # Override this in subclasses to define a static display.
79
+ def table_template
80
+ # implement this in subclasses to define the column template
81
+ end
82
+
83
+ # Add a column to the table
55
84
  #
85
+ # @param column [Columns::Base] The column object to add
56
86
  # @return [void]
57
- def display_template
58
- instance_exec(&@_content_block) if @_content_block
87
+ # @raise [ArgumentError] If a column with the same key already exists
88
+ def add_column(column)
89
+ raise ArgumentError, "Column '#{column.key}' already exists" if @columns.key?(column.key)
90
+
91
+ @columns[column.key] = column
92
+ end
93
+
94
+ def column(key, **, &)
95
+ add_column(column_class.new(key, self, **, &))
96
+ end
97
+
98
+ def selection_column(key, **, &)
99
+ raise "Selection column already added" if @has_selection_column
100
+
101
+ @has_selection_column = true
102
+ add_column(selection_column_class.new(key, self, **, &))
103
+ end
104
+
105
+ def column_group(key, **, &)
106
+ @has_grouped_columns = true
107
+ add_column(column_group_class.new(key, self, **, &))
108
+ end
109
+
110
+ def actions(**, &)
111
+ raise "Action column already added" if @has_action_column
112
+
113
+ @has_action_column = true
114
+ add_column(actions_column_class.new(:phlexi_table_actions, self, label: "Actions", **, &))
115
+ end
116
+
117
+ def sample
118
+ collection[0]
119
+ end
120
+
121
+ def wrapped_sample
122
+ @wrapped_sample ||= WrappedObject.new(sample, index: -1, display_class: self.class::Display)
123
+ end
124
+
125
+ def dom_id
126
+ key
127
+ end
128
+
129
+ def column_class
130
+ self.class::DataColumn
131
+ end
132
+
133
+ def selection_column_class
134
+ self.class::SelectionColumn
135
+ end
136
+
137
+ def actions_column_class
138
+ self.class::ActionsColumn
139
+ end
140
+
141
+ def column_group_class
142
+ self.class::ColumnGroup
59
143
  end
60
144
 
61
145
  protected
62
146
 
63
- attr_reader :options, :attributes, :namespace_klass, :builder_klass
147
+ # Render the complete table structure
148
+ #
149
+ # @return [void]
150
+ def render_table
151
+ div(**table_wrapper_attributes) {
152
+ table(**table_attributes) do
153
+ render_table_caption
154
+ render_table_header
155
+ render_table_body
156
+ render_table_footer
157
+ end
158
+ }
159
+ end
64
160
 
65
- # Initializes the object and key based on the given record.
161
+ # Render the table caption
66
162
  #
67
- # @param record [ActiveModel::Model, Symbol, String] The display's associated record or key
68
163
  # @return [void]
69
- def initialize_object_and_key(record)
70
- @key = options.delete(:key) || options.delete(:as)
164
+ def render_table_caption
165
+ return unless has_table_caption? || has_table_description?
71
166
 
72
- case record
73
- when String, Symbol
74
- @object = nil
75
- @key = record
76
- else
77
- @object = record
78
- @key = if @key.nil? && object.respond_to?(:model_name) && object.model_name.respond_to?(:param_key) && object.model_name.param_key.present?
79
- object.model_name.param_key
80
- else
81
- :object
167
+ caption(**table_caption_attributes) {
168
+ plain table_caption if has_table_caption?
169
+ if has_table_description?
170
+ p(**table_description_attributes) {
171
+ table_description
172
+ }
173
+ end
174
+ }
175
+ end
176
+
177
+ # Render the table header
178
+ #
179
+ # @return [void]
180
+ def render_table_header
181
+ thead(**table_header_attributes) do
182
+ if @has_grouped_columns
183
+ tr(**table_header_grouping_row_attributes) do
184
+ blanks = 0
185
+ columns.each_value do |column|
186
+ if column.is_a?(Phlexi::Table::Components::Concerns::GroupsColumns)
187
+ th(**table_header_grouping_cell_attributes(blanks)) {} if blanks > 0
188
+ th(id: column.dom_id, **table_header_grouping_cell_attributes(column.colspan)) { column.label }
189
+ blanks = 0
190
+ else
191
+ blanks += 1
192
+ end
193
+ end
194
+ th(**table_header_grouping_cell_attributes(blanks)) { whitespace } if blanks > 0
195
+ end
196
+ end
197
+
198
+ tr(**table_header_row_attributes) do
199
+ columns.each_value do |column|
200
+ if column.is_a?(Phlexi::Table::Components::Concerns::GroupsColumns)
201
+ column.columns.each_value do |column|
202
+ th(**table_header_cell_attributes(column)) { render column.header_cell }
203
+ end
204
+ else
205
+ th(**table_header_cell_attributes(column)) { render column.header_cell }
206
+ end
207
+ end
82
208
  end
83
209
  end
84
- @key = @key.to_sym
85
210
  end
86
211
 
87
- # Initializes the namespace for the display.
212
+ # Render the table body
88
213
  #
89
214
  # @return [void]
90
- def initialize_namespace
91
- @namespace = namespace_klass.root(key, object: object, builder_klass: builder_klass)
215
+ def render_table_body
216
+ tbody(**table_body_attributes) do
217
+ collection.each_with_index do |object, index|
218
+ wrapped_object = WrappedObject.new(object, index:, display_class: self.class::Display)
219
+ render_table_body_row(wrapped_object)
220
+ end
221
+ end
92
222
  end
93
- # Retrieves the display's CSS classes.
223
+
224
+ # Render a table body row
94
225
  #
95
- # @return [String] The display's CSS classes
96
- attr_reader :display_class
226
+ # @param wrapped_object [Object] The current item from the collection
227
+ # @return [void]
228
+ def render_table_body_row(wrapped_object)
229
+ tr(**table_body_row_attributes(wrapped_object)) do
230
+ columns.each_value do |column|
231
+ if column.is_a?(Phlexi::Table::Components::Concerns::GroupsColumns)
232
+ column.columns.each_value do |column|
233
+ td(**table_data_cell_attributes(wrapped_object, column)) { render column.data_cell(wrapped_object) }
234
+ end
235
+ elsif column.is_a?(actions_column_class)
236
+ td(**table_data_cell_attributes(wrapped_object, column)) { column.render_actions(wrapped_object) }
237
+ else
238
+ td(**table_data_cell_attributes(wrapped_object, column)) { render column.data_cell(wrapped_object) }
239
+ end
240
+ end
241
+ end
242
+ end
97
243
 
98
- # Generates the display attributes hash.
244
+ # Render the table footer
99
245
  #
100
- # @return [Hash] The display attributes
101
- def display_attributes
102
- mix({
103
- id: @namespace.dom_id,
104
- class: display_class
105
- }, attributes)
246
+ # @return [void]
247
+ def render_table_footer
248
+ # tfoot(**table_footer_attributes) do
249
+ # # Implement footer content if needed
250
+ # end
106
251
  end
107
252
 
108
253
  private
109
254
 
110
- def default_namespace_klass
111
- self.class::Namespace
255
+ def table_wrapper_attributes
256
+ {
257
+ id: @options[:id] || "#{dom_id}_table_wrapper",
258
+ class: tokens("phlexi_table_wrapper", themed(:wrapper))
259
+ }
260
+ end
261
+
262
+ # Get the attributes for the table element
263
+ #
264
+ # @return [Hash] The table attributes
265
+ def table_attributes
266
+ {
267
+ id: @options[:id] || "#{dom_id}_table",
268
+ class: tokens("phlexi_table", themed(:base), @options[:class])
269
+ }
270
+ end
271
+
272
+ # Get the attributes for the table caption element
273
+ #
274
+ # @return [Hash] The caption attributes
275
+ def table_caption_attributes
276
+ {
277
+ id: "#{dom_id}_table_caption",
278
+ class: tokens("phlexi_table_caption", themed(:caption))
279
+ }
280
+ end
281
+
282
+ # Get the attributes for the table description
283
+ #
284
+ # @return [Hash] The description attributes
285
+ def table_description_attributes
286
+ {
287
+ id: "#{dom_id}_table_description",
288
+ class: tokens("phlexi_table_description", themed(:description))
289
+ }
290
+ end
291
+
292
+ # Get the attributes for the table header element
293
+ #
294
+ # @return [Hash] The header attributes
295
+ def table_header_attributes
296
+ {
297
+ id: "#{dom_id}_table_header",
298
+ class: tokens("phlexi_table_header", themed(:header))
299
+ }
300
+ end
301
+
302
+ def table_header_grouping_row_attributes
303
+ {
304
+ id: "#{dom_id}_table_header_grouping_row",
305
+ class: tokens("phlexi_table_header_grouping_row", themed(:header_grouping_row))
306
+ }
307
+ end
308
+
309
+ def table_header_grouping_cell_attributes(colspan)
310
+ {
311
+ colspan:,
312
+ class: tokens("phlexi_table_header_grouping_cell", themed(:header_grouping_cell))
313
+ }
314
+ end
315
+
316
+ # Get the attributes for the table header row element
317
+ #
318
+ # @return [Hash] The header row attributes
319
+ def table_header_row_attributes
320
+ {
321
+ id: "#{dom_id}_table_header_row",
322
+ class: tokens("phlexi_table_header_row", themed(:header_row))
323
+ }
324
+ end
325
+
326
+ # Get the attributes for a table header cell element
327
+ #
328
+ # @param column [Columns::Base] The column object
329
+ # @return [Hash] The header cell attributes
330
+ def table_header_cell_attributes(column)
331
+ mix(
332
+ {
333
+ scope: "col",
334
+ class: tokens("phlexi_table_header_cell", themed(:header_cell))
335
+ },
336
+ column.header_cell_attributes
337
+ )
338
+ end
339
+
340
+ # Get the attributes for the table body element
341
+ #
342
+ # @return [Hash] The body attributes
343
+ def table_body_attributes
344
+ {
345
+ id: "#{dom_id}_table_body",
346
+ class: tokens("phlexi_table_body", themed(:body))
347
+ }
348
+ end
349
+
350
+ # Get the attributes for a table body row element
351
+ #
352
+ # @param wrapped_object [Object] The current item from the collection
353
+ # @return [Hash] The body row attributes
354
+ def table_body_row_attributes(wrapped_object)
355
+ {
356
+ id: "#{dom_id}_table_row_#{wrapped_object.identifier}",
357
+ class: tokens("phlexi_table_body_row", themed(:body_row))
358
+ }
112
359
  end
113
360
 
114
- def default_builder_klass
115
- self.class::FieldBuilder
361
+ # Get the attributes for a table body cell element
362
+ #
363
+ # @param wrapped_object [Object] The current item from the collection
364
+ # @param column [Columns::Base] The column object
365
+ # @return [Hash] The body cell attributes
366
+ def table_data_cell_attributes(wrapped_object, column)
367
+ mix(
368
+ {
369
+ id: "#{dom_id}_table_row_#{wrapped_object.identifier}_#{column.key}",
370
+ class: tokens("phlexi_table_data_cell", themed(:body_cell))
371
+ },
372
+ column.data_cell_attributes(wrapped_object)
373
+ )
374
+ end
375
+
376
+ # Get the attributes for the table footer element
377
+ #
378
+ # @return [Hash] The footer attributes
379
+ def table_footer_attributes
380
+ {
381
+ id: "#{dom_id}_table_footer",
382
+ class: tokens("phlexi_table_footer", themed(:footer))
383
+ }
384
+ end
385
+
386
+ def initialize_key
387
+ # always pop these keys
388
+ # add support for `as` to make it more rails friendly
389
+ @key = options.delete(:key) || options.delete(:as)
390
+ if @key.nil?
391
+ @key = if sample.respond_to?(:model_name) && sample.model_name.respond_to?(:param_key) && sample.model_name.param_key.present?
392
+ sample.model_name.plural.underscore
393
+ else
394
+ sample.class.name.demodulize.pluralize.underscore
395
+ end
396
+ end
397
+ @key = @key.to_sym
116
398
  end
117
399
  end
118
400
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class ActionsColumn < Base
7
+ include Phlexi::Table::Components::Concerns::DisplaysHeader
8
+
9
+ def initialize(*, **, &block)
10
+ raise ArgumentError, "block is required" unless block.present?
11
+
12
+ super(*, **)
13
+ @block = block
14
+ end
15
+
16
+ def label(label = nil)
17
+ if label.nil?
18
+ options[:label]
19
+ else
20
+ options[:label] = label
21
+ self
22
+ end
23
+ end
24
+
25
+ def render_actions(object)
26
+ @block.call(object)
27
+ end
28
+
29
+ def dom_id
30
+ "#{super}_actions_cell"
31
+ end
32
+
33
+ def data_cell_attributes(object)
34
+ @attributes
35
+ end
36
+
37
+ def type = "actions"
38
+
39
+ def alignment = nil
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,34 +3,38 @@
3
3
  module Phlexi
4
4
  module Table
5
5
  module Components
6
- class Base < COMPONENT_BASE
7
- attr_reader :field, :attributes
6
+ class Base
7
+ include Phlex::Helpers
8
+ include Phlexi::Table::HTML::Behaviour
8
9
 
9
- def initialize(field, **attributes)
10
- @field = field
11
- @attributes = attributes
10
+ attr_reader :key, :parent, :options
11
+
12
+ delegate :sample, :wrapped_sample, to: :parent
13
+
14
+ def initialize(key, parent, **options)
15
+ @key = key
16
+ @parent = parent
17
+ @options = options
12
18
 
13
19
  build_attributes
14
- append_attribute_classes
15
20
  end
16
21
 
17
- protected
18
-
19
- def build_attributes
20
- attributes.fetch(:id) { attributes[:id] = "#{field.dom.id}_#{component_name}" }
22
+ def dom_id
23
+ "#{parent.dom_id}_#{key}"
21
24
  end
22
25
 
23
- def append_attribute_classes
24
- return if attributes[:class] == false
26
+ private
25
27
 
26
- attributes[:class] = tokens(
27
- component_name,
28
- attributes[:class]
29
- )
28
+ def build_attributes
29
+ @attributes = {
30
+ class: tokens(
31
+ type
32
+ )
33
+ }
30
34
  end
31
35
 
32
- def component_name
33
- @component_name ||= self.class.name.demodulize.underscore
36
+ def type
37
+ options[:as] || wrapped_sample.field(key).inferred_field_type
34
38
  end
35
39
  end
36
40
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class Column < Base
7
+ include Phlexi::Table::Components::Options::Labels
8
+ include Phlexi::Table::Components::Options::Alignment
9
+ include Phlexi::Table::Components::Concerns::DisplaysHeader
10
+ include Phlexi::Table::Components::Concerns::DisplaysData
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ module Phlexi
2
+ module Table
3
+ module Components
4
+ class ColumnGroup < Base
5
+ include Phlexi::Table::Components::Options::Labels
6
+ include Phlexi::Table::Components::Concerns::DisplaysHeader
7
+ include Phlexi::Table::Components::Concerns::GroupsColumns
8
+
9
+ def colspan
10
+ @columns.size
11
+ end
12
+
13
+ def dom_id
14
+ "#{super}_header_grouping_cell"
15
+ end
16
+
17
+ def type = "column_group"
18
+
19
+ def alignment = nil
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ module Concerns
7
+ module DisplaysData
8
+ extend ActiveSupport::Concern
9
+
10
+ def data_cell(wrapped_object)
11
+ raise NotImplementedError, "#{self.class} must implement #data_cell"
12
+ end
13
+
14
+ def data_cell_attributes(wrapped_object)
15
+ attributes = @attributes.dup
16
+ attributes[:class] = tokens(
17
+ attributes[:class],
18
+ themed(:"align_#{alignment}"),
19
+ themed(:"#{type}_column")
20
+ )
21
+ attributes
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ module Concerns
7
+ module DisplaysHeader
8
+ extend ActiveSupport::Concern
9
+
10
+ def header_cell
11
+ HeaderCell.new(label)
12
+ end
13
+
14
+ def header_cell_attributes
15
+ attributes = @attributes.dup
16
+ attributes[:id] = "#{dom_id}_header_cell"
17
+ attributes[:class] = tokens(
18
+ attributes[:class],
19
+ themed(:"align_#{alignment}"),
20
+ themed(:"#{type}_column")
21
+ )
22
+ attributes
23
+ end
24
+
25
+ def colspan = 1
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end