phlexi-table 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ module Concerns
7
+ module GroupsColumns
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ attr_reader :columns
12
+ end
13
+
14
+ def initialize(*, **, &)
15
+ super(*, **)
16
+
17
+ @columns = {}
18
+ yield self if block_given?
19
+ end
20
+
21
+ def column(key, **, &)
22
+ add_column(parent.column_class.new(key, self, **, &))
23
+ end
24
+
25
+ private
26
+
27
+ def add_column(column)
28
+ raise ArgumentError, "Column '#{column.key}' already exists" if @columns.key?(column.key) || parent.columns.key?(column.key)
29
+
30
+ @columns[column.key] = column
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class DataColumn < Column
7
+ def initialize(*, **, &block)
8
+ super(*, **)
9
+ @block = block
10
+ end
11
+
12
+ def header_cell
13
+ SortableHeaderCell.new(label, sort_params:)
14
+ end
15
+
16
+ def data_cell(wrapped_object)
17
+ if @block
18
+ @block.call(wrapped_object, key)
19
+ else
20
+ field = wrapped_object.field(key)
21
+ field.send(:"#{field.inferred_field_component}_tag")
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def sort_params
28
+ options[:sort_params]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class HeaderCell < Phlexi::Table::HTML
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+
11
+ def view_template
12
+ div(class: themed(:header_cell_content_wrapper)) do
13
+ plain @value.to_s
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ module Options
7
+ module Alignment
8
+ def alignment(alignment = nil)
9
+ if alignment.nil?
10
+ options[:align] = options.fetch(:align) { calculate_alignment }
11
+ else
12
+ options[:align] = alignment
13
+ self
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def calculate_alignment
20
+ case type
21
+ when :integer, :float, :decimal
22
+ :end
23
+ else
24
+ :start
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ module Options
7
+ module Labels
8
+ def label(label = nil)
9
+ if label.nil?
10
+ options[:label] = options.fetch(:label) { calculate_label }
11
+ else
12
+ options[:label] = label
13
+ self
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def calculate_label
20
+ if sample.class.respond_to?(:human_attribute_name)
21
+ sample.class.human_attribute_name(key.to_s, {base: sample})
22
+ else
23
+ key.to_s.humanize
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class SelectionCell < Phlexi::Table::HTML
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+
11
+ def view_template
12
+ input(type: :checkbox, value: @value, class: themed(:selection_checkbox))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class SelectionColumn < Column
7
+ def header_cell
8
+ SelectionCell.new("all")
9
+ end
10
+
11
+ def data_cell(wrapped_object)
12
+ SelectionCell.new(wrapped_object.field(key).dom.value)
13
+ end
14
+
15
+ def data_cell_attributes(wrapped_object)
16
+ {scope: :row}.merge(super)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Components
6
+ class SortableHeaderCell < HeaderCell
7
+ def initialize(value, sort_params:)
8
+ @value = value
9
+ @sort_params = sort_params
10
+ end
11
+
12
+ def view_template
13
+ div(class: themed(:header_cell_content_wrapper)) do
14
+ if !@sort_params
15
+ plain @value.to_s
16
+ next
17
+ end
18
+
19
+ a(class: themed(:header_cell_sort_wrapper), href: @sort_params[:url]) do
20
+ plain @value.to_s
21
+
22
+ sort_icon = themed(:sort_icon)
23
+ sort_icon_active = themed(:sort_icon_active)
24
+
25
+ span(class: themed(:header_cell_sort_indicator)) {
26
+ svg(
27
+ class: tokens(sort_icon, -> { @sort_params[:direction] != "DESC" } => sort_icon_active),
28
+ aria_hidden: "true",
29
+ xmlns: "http://www.w3.org/2000/svg",
30
+ fill: "none",
31
+ viewbox: "0 0 10 6"
32
+ ) do |s|
33
+ s.path(
34
+ stroke: "currentColor",
35
+ stroke_linecap: "round",
36
+ stroke_linejoin: "round",
37
+ stroke_width: "2",
38
+ d: "M9 5 5 1 1 5"
39
+ )
40
+ end
41
+ svg(
42
+ class: tokens(sort_icon, -> { @sort_params[:direction] != "ASC" } => sort_icon_active),
43
+ aria_hidden: "true",
44
+ xmlns: "http://www.w3.org/2000/svg",
45
+ fill: "none",
46
+ viewbox: "0 0 10 6"
47
+ ) do |s|
48
+ s.path(
49
+ stroke: "currentColor",
50
+ stroke_linecap: "round",
51
+ stroke_linejoin: "round",
52
+ stroke_width: "2",
53
+ d: "M1 1 5 5 9 1"
54
+ )
55
+ end
56
+ }
57
+ end
58
+
59
+ next if @sort_params[:position].nil?
60
+
61
+ sort_index_clear_link = themed(:sort_index_clear_link)
62
+ sort_index_clear_link_text = themed(:sort_index_clear_link_text)
63
+ sort_index_clear_link_icon = themed(:sort_index_clear_link_icon)
64
+
65
+ a(href: @sort_params[:reset_url], title: "Clear sort", class: sort_index_clear_link) {
66
+ span(class: sort_index_clear_link_text) { (@sort_params[:position] + 1).to_s }
67
+ span(class: sort_index_clear_link_icon) { "✕" }
68
+ }
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,6 @@
1
+ module Phlexi
2
+ module Table
3
+ class DisplayTheme < Phlexi::Display::Theme
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module Phlexi
2
+ module Table
3
+ class HTML < (defined?(::ApplicationComponent) ? ::ApplicationComponent : Phlex::HTML)
4
+ module Behaviour
5
+ protected
6
+
7
+ def themed(component)
8
+ Phlexi::Table::Theme.instance.resolve_theme(component)
9
+ end
10
+ end
11
+
12
+ include Behaviour
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Table
5
+ module Options
6
+ module Captions
7
+ def table_caption(caption = nil)
8
+ if caption.nil?
9
+ options[:caption]
10
+ else
11
+ options[:caption] = caption
12
+ self
13
+ end
14
+ end
15
+
16
+ def has_table_caption?
17
+ table_caption.present?
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Phlexi
4
4
  module Table
5
- module FieldOptions
6
- module Description
7
- def description(description = nil)
5
+ module Options
6
+ module Descriptions
7
+ def table_description(description = nil)
8
8
  if description.nil?
9
9
  options[:description]
10
10
  else
@@ -13,8 +13,8 @@ module Phlexi
13
13
  end
14
14
  end
15
15
 
16
- def has_description?
17
- description.present?
16
+ def has_table_description?
17
+ table_description.present?
18
18
  end
19
19
  end
20
20
  end
@@ -0,0 +1,25 @@
1
+ module Phlexi
2
+ module Table
3
+ class Theme < Phlexi::Field::Theme
4
+ def self.theme
5
+ {
6
+ wrapper: nil,
7
+ base: nil,
8
+ caption: nil,
9
+ description: nil,
10
+ header: nil,
11
+ header_grouping_row: :header_row,
12
+ header_grouping_cell: :header_row_cell,
13
+ header_row: nil,
14
+ header_cell: nil,
15
+ body_row: nil,
16
+ body_cell: nil,
17
+ name_column: nil,
18
+ align_start: nil,
19
+ align_end: nil,
20
+ selection_checkbox: nil
21
+ }.freeze
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlexi
4
4
  module Table
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.3"
6
6
  end
7
7
  end
@@ -0,0 +1,27 @@
1
+ module Phlexi
2
+ module Table
3
+ class WrappedObject
4
+ attr_reader :unwrapped, :index
5
+
6
+ delegate :field, to: :as_display
7
+
8
+ def initialize(object, index:, display_class:)
9
+ @unwrapped = object
10
+ @index = index
11
+ @display_class = display_class
12
+ end
13
+
14
+ def identifier
15
+ @identifier ||= Phlexi::Field.object_primary_key(unwrapped) || (index + 1)
16
+ end
17
+
18
+ def value_of(key)
19
+ @unwrapped.try(key)
20
+ end
21
+
22
+ def as_display
23
+ @as_display ||= @display_class.new(unwrapped)
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/phlexi/table.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "zeitwerk"
4
4
  require "phlex"
5
+ require "phlexi-field"
6
+ require "phlexi-display"
5
7
  require "active_support/core_ext/object/blank"
6
8
 
7
9
  module Phlexi
@@ -9,18 +11,15 @@ module Phlexi
9
11
  Loader = Zeitwerk::Loader.new.tap do |loader|
10
12
  loader.tag = File.basename(__FILE__, ".rb")
11
13
  loader.inflector.inflect(
12
- "phlexi-display" => "Phlexi",
14
+ "phlexi-table" => "Phlexi",
13
15
  "phlexi" => "Phlexi",
14
- "dom" => "DOM"
16
+ "html" => "HTML"
15
17
  )
18
+ loader.ignore("#{__dir__}/table/field_options copy")
16
19
  loader.push_dir(File.expand_path("..", __dir__))
17
20
  loader.setup
18
21
  end
19
22
 
20
- COMPONENT_BASE = (defined?(::ApplicationComponent) ? ::ApplicationComponent : Phlex::HTML)
21
-
22
- NIL_VALUE = :__i_phlexi_display_nil_value_i__
23
-
24
23
  class Error < StandardError; end
25
24
  end
26
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlexi-table
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-26 00:00:00.000000000 Z
11
+ date: 2024-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: phlexi-field
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: phlexi-display
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -185,31 +213,27 @@ files:
185
213
  - lib/phlexi-table.rb
186
214
  - lib/phlexi/table.rb
187
215
  - lib/phlexi/table/base.rb
216
+ - lib/phlexi/table/components/actions_column.rb
188
217
  - lib/phlexi/table/components/base.rb
189
- - lib/phlexi/table/components/concerns/displays_value.rb
190
- - lib/phlexi/table/components/date_time.rb
191
- - lib/phlexi/table/components/description.rb
192
- - lib/phlexi/table/components/hint.rb
193
- - lib/phlexi/table/components/label.rb
194
- - lib/phlexi/table/components/number.rb
195
- - lib/phlexi/table/components/placeholder.rb
196
- - lib/phlexi/table/components/string.rb
197
- - lib/phlexi/table/components/wrapper.rb
198
- - lib/phlexi/table/field_options/associations.rb
199
- - lib/phlexi/table/field_options/attachments.rb
200
- - lib/phlexi/table/field_options/description.rb
201
- - lib/phlexi/table/field_options/hints.rb
202
- - lib/phlexi/table/field_options/inferred_types.rb
203
- - lib/phlexi/table/field_options/labels.rb
204
- - lib/phlexi/table/field_options/placeholders.rb
205
- - lib/phlexi/table/field_options/themes.rb
206
- - lib/phlexi/table/structure/dom.rb
207
- - lib/phlexi/table/structure/field_builder.rb
208
- - lib/phlexi/table/structure/field_collection.rb
209
- - lib/phlexi/table/structure/namespace.rb
210
- - lib/phlexi/table/structure/namespace_collection.rb
211
- - lib/phlexi/table/structure/node.rb
218
+ - lib/phlexi/table/components/column.rb
219
+ - lib/phlexi/table/components/column_group.rb
220
+ - lib/phlexi/table/components/concerns/displays_data.rb
221
+ - lib/phlexi/table/components/concerns/displays_header.rb
222
+ - lib/phlexi/table/components/concerns/groups_columns.rb
223
+ - lib/phlexi/table/components/data_column.rb
224
+ - lib/phlexi/table/components/header_cell.rb
225
+ - lib/phlexi/table/components/options/alignment.rb
226
+ - lib/phlexi/table/components/options/labels.rb
227
+ - lib/phlexi/table/components/selection_cell.rb
228
+ - lib/phlexi/table/components/selection_column.rb
229
+ - lib/phlexi/table/components/sortable_header_cell.rb
230
+ - lib/phlexi/table/display_theme.rb
231
+ - lib/phlexi/table/html.rb
232
+ - lib/phlexi/table/options/captions.rb
233
+ - lib/phlexi/table/options/descriptions.rb
234
+ - lib/phlexi/table/theme.rb
212
235
  - lib/phlexi/table/version.rb
236
+ - lib/phlexi/table/wrapped_object.rb
213
237
  - sig/phlexi/table.rbs
214
238
  homepage: https://github.com/radioactive-labs/phlexi-table
215
239
  licenses:
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Table
5
- module Components
6
- module Concerns
7
- module TablesValue
8
- def view_template
9
- value = normalize_value(field.value)
10
- if value.blank?
11
- render field.placeholder_tag(**@placeholder_attributes)
12
- else
13
- render_value(value)
14
- end
15
- end
16
-
17
- # Renders the field value for display.
18
- #
19
- # @return [String] the formatted field value for display.
20
- def render_value(value)
21
- raise NotImplementedError, "#{self.class}#render_value"
22
- # format_value()
23
- end
24
-
25
- protected
26
-
27
- def build_attributes
28
- super
29
-
30
- @placeholder_attributes = attributes.delete(:placeholder_attributes) || {}
31
- attributes[:id] = field.dom.id if attributes[:id] == "#{field.dom.id}_#{component_name}"
32
- end
33
-
34
- # def format_value(value)
35
- # case value
36
- # when Array
37
- # format_array_value(value)
38
- # else
39
- # format_single_value(value)
40
- # end
41
- # end
42
-
43
- # def format_array_value(array)
44
- # array.map { |item| format_single_value(item) }.join(", ")
45
- # end
46
-
47
- def normalize_value(value)
48
- value.to_s
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Table
5
- module Components
6
- class DateTime < Base
7
- include Concerns::TablesValue
8
-
9
- # Renders the date time value
10
- #
11
- # @param value [String, Date, Time, DateTime] The value to be rendered
12
- # @return [void]
13
- def render_value(value)
14
- formatted_value = format_date_time(value)
15
- p(**attributes) { formatted_value }
16
- end
17
-
18
- protected
19
-
20
- def build_attributes
21
- super
22
-
23
- @options = {
24
- format: default_format
25
- }.merge(attributes.delete(:options) || {}).compact
26
- end
27
-
28
- private
29
-
30
- def format_date_time(value)
31
- I18n.l(value, **@options)
32
- end
33
-
34
- def default_format
35
- :long
36
- end
37
-
38
- def normalize_value(value)
39
- case value
40
- when Date, DateTime, Time, nil
41
- value
42
- else
43
- raise ArgumentError, "Value must be a Date, DateTime or Time object. #{value.inspect} given."
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Table
5
- module Components
6
- class Description < Base
7
- def view_template
8
- p(**attributes) {
9
- field.description
10
- }
11
- end
12
-
13
- private
14
-
15
- def render?
16
- field.has_description?
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Table
5
- module Components
6
- class Hint < Base
7
- def view_template
8
- p(**attributes) do
9
- field.hint
10
- end
11
- end
12
-
13
- private
14
-
15
- def render?
16
- field.has_hint?
17
- end
18
- end
19
- end
20
- end
21
- end