better_ui 0.4.0 → 0.5.1

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +141 -189
  3. data/app/assets/stylesheets/better_ui/_base.scss +9 -0
  4. data/app/assets/stylesheets/better_ui/_components.scss +2 -0
  5. data/app/assets/stylesheets/better_ui/_utilities.scss +14 -0
  6. data/app/assets/stylesheets/better_ui/application.css +3 -1
  7. data/app/assets/stylesheets/better_ui/components/_avatar.scss +200 -0
  8. data/app/assets/stylesheets/better_ui/components/_badge.scss +154 -0
  9. data/app/assets/stylesheets/better_ui/components/_breadcrumb.scss +106 -0
  10. data/app/assets/stylesheets/better_ui/components/_button.scss +105 -0
  11. data/app/assets/stylesheets/better_ui/components/_card.scss +60 -0
  12. data/app/assets/stylesheets/better_ui/components/_heading.scss +81 -0
  13. data/app/assets/stylesheets/better_ui/components/_icon.scss +134 -0
  14. data/app/assets/stylesheets/better_ui/components/_index.scss +17 -0
  15. data/app/assets/stylesheets/better_ui/components/_link.scss +100 -0
  16. data/app/assets/stylesheets/better_ui/components/_panel.scss +104 -0
  17. data/app/assets/stylesheets/better_ui/components/_spinner.scss +129 -0
  18. data/app/assets/stylesheets/better_ui/components/_table.scss +156 -0
  19. data/app/assets/stylesheets/better_ui/components/_variables.scss +1 -0
  20. data/app/assets/stylesheets/better_ui.scss +4 -0
  21. data/app/components/better_ui/application/alert_component.html.erb +1 -1
  22. data/app/components/better_ui/application/alert_component.rb +95 -89
  23. data/app/components/better_ui/application/card_component.html.erb +24 -0
  24. data/app/components/better_ui/application/card_component.rb +53 -0
  25. data/app/components/better_ui/application/card_container_component.html.erb +8 -0
  26. data/app/components/better_ui/application/card_container_component.rb +14 -0
  27. data/app/components/better_ui/application/toast_component.rb +92 -57
  28. data/app/components/better_ui/general/avatar_component.html.erb +19 -0
  29. data/app/components/better_ui/general/avatar_component.rb +171 -0
  30. data/app/components/better_ui/general/badge_component.html.erb +19 -0
  31. data/app/components/better_ui/general/badge_component.rb +135 -0
  32. data/app/components/better_ui/general/breadcrumb_component.html.erb +7 -31
  33. data/app/components/better_ui/general/breadcrumb_component.rb +64 -66
  34. data/app/components/better_ui/general/button_component.html.erb +6 -6
  35. data/app/components/better_ui/general/button_component.rb +62 -95
  36. data/app/components/better_ui/general/heading_component.html.erb +1 -25
  37. data/app/components/better_ui/general/heading_component.rb +20 -113
  38. data/app/components/better_ui/general/icon_component.rb +37 -61
  39. data/app/components/better_ui/general/link_component.html.erb +17 -0
  40. data/app/components/better_ui/general/link_component.rb +132 -0
  41. data/app/components/better_ui/general/panel_component.rb +51 -56
  42. data/app/components/better_ui/general/spinner_component.html.erb +15 -0
  43. data/app/components/better_ui/general/spinner_component.rb +79 -0
  44. data/app/components/better_ui/general/table_component.html.erb +56 -20
  45. data/app/components/better_ui/general/table_component.rb +89 -87
  46. data/app/helpers/better_ui/general/components/avatar_helper.rb +17 -0
  47. data/app/helpers/better_ui/general/components/badge_helper.rb +17 -0
  48. data/app/helpers/better_ui/general/components/breadcrumb_helper.rb +17 -0
  49. data/app/helpers/better_ui/general/components/button_helper.rb +17 -0
  50. data/app/helpers/better_ui/general/components/heading_helper.rb +17 -0
  51. data/app/helpers/better_ui/general/components/icon_helper.rb +17 -0
  52. data/app/helpers/better_ui/general/components/link_helper.rb +17 -0
  53. data/app/helpers/better_ui/general/components/panel_helper.rb +16 -0
  54. data/app/helpers/better_ui/general/components/spinner_helper.rb +17 -0
  55. data/app/helpers/better_ui/general/components/table_helper.rb +17 -0
  56. data/app/helpers/better_ui/general_helper.rb +15 -0
  57. data/app/helpers/better_ui_helper.rb +12 -0
  58. data/app/views/components/better_ui/general/table/_custom_body_row.html.erb +17 -0
  59. data/app/views/components/better_ui/general/table/_custom_footer_rows.html.erb +17 -0
  60. data/app/views/components/better_ui/general/table/_custom_header_rows.html.erb +12 -0
  61. data/config/routes.rb +2 -13
  62. data/lib/better_ui/engine.rb +66 -16
  63. data/lib/better_ui/version.rb +1 -1
  64. data/lib/better_ui.rb +12 -0
  65. data/lib/generators/better_ui/install_generator.rb +103 -0
  66. data/lib/generators/better_ui/stylesheet_generator.rb +159 -0
  67. data/lib/generators/better_ui/templates/README +125 -0
  68. data/lib/generators/better_ui/templates/components/_avatar.scss +200 -0
  69. data/lib/generators/better_ui/templates/components/_badge.scss +154 -0
  70. data/lib/generators/better_ui/templates/components/_breadcrumb.scss +106 -0
  71. data/lib/generators/better_ui/templates/components/_button.scss +109 -0
  72. data/lib/generators/better_ui/templates/components/_card.scss +60 -0
  73. data/lib/generators/better_ui/templates/components/_heading.scss +81 -0
  74. data/lib/generators/better_ui/templates/components/_icon.scss +134 -0
  75. data/lib/generators/better_ui/templates/components/_index.scss +17 -0
  76. data/lib/generators/better_ui/templates/components/_link.scss +100 -0
  77. data/lib/generators/better_ui/templates/components/_panel.scss +104 -0
  78. data/lib/generators/better_ui/templates/components/_spinner.scss +129 -0
  79. data/lib/generators/better_ui/templates/components/_table.scss +156 -0
  80. data/lib/generators/better_ui/templates/components/_variables.scss +0 -0
  81. data/lib/generators/better_ui/templates/components_stylesheet.scss +35 -0
  82. data/lib/generators/better_ui/templates/index.scss +18 -0
  83. data/lib/generators/better_ui/templates/initializer.rb +41 -0
  84. metadata +120 -49
  85. data/app/assets/javascripts/better_ui/controllers/navbar_controller.js +0 -138
  86. data/app/assets/javascripts/better_ui/controllers/sidebar_controller.js +0 -211
  87. data/app/assets/javascripts/better_ui/controllers/toast_controller.js +0 -161
  88. data/app/assets/javascripts/better_ui/index.js +0 -159
  89. data/app/assets/javascripts/better_ui/toast_manager.js +0 -77
  90. data/app/components/better_ui/theme_helper.rb +0 -169
  91. data/app/controllers/better_ui/docs_controller.rb +0 -34
  92. data/app/helpers/better_ui_application_helper.rb +0 -99
@@ -0,0 +1,132 @@
1
+ module BetterUi
2
+ module General
3
+ class LinkComponent < ViewComponent::Base
4
+ attr_reader :label, :href, :theme, :icon, :classes, :active, :data, :method, :target
5
+
6
+ # Temi di colore disponibili
7
+ LINK_THEME = {
8
+ default: {
9
+ link: "bui-link--default",
10
+ active: "bui-link--active bui-link--default",
11
+ text: "bui-link--text bui-link--default"
12
+ },
13
+ white: {
14
+ link: "bui-link--white",
15
+ active: "bui-link--active bui-link--white",
16
+ text: "bui-link--text bui-link--white"
17
+ },
18
+ red: {
19
+ link: "bui-link--red",
20
+ active: "bui-link--active bui-link--red",
21
+ text: "bui-link--text bui-link--red"
22
+ },
23
+ rose: {
24
+ link: "bui-link--rose",
25
+ active: "bui-link--active bui-link--rose",
26
+ text: "bui-link--text bui-link--rose"
27
+ },
28
+ orange: {
29
+ link: "bui-link--orange",
30
+ active: "bui-link--active bui-link--orange",
31
+ text: "bui-link--text bui-link--orange"
32
+ },
33
+ green: {
34
+ link: "bui-link--green",
35
+ active: "bui-link--active bui-link--green",
36
+ text: "bui-link--text bui-link--green"
37
+ },
38
+ blue: {
39
+ link: "bui-link--blue",
40
+ active: "bui-link--active bui-link--blue",
41
+ text: "bui-link--text bui-link--blue"
42
+ },
43
+ yellow: {
44
+ link: "bui-link--yellow",
45
+ active: "bui-link--active bui-link--yellow",
46
+ text: "bui-link--text bui-link--yellow"
47
+ },
48
+ violet: {
49
+ link: "bui-link--violet",
50
+ active: "bui-link--active bui-link--violet",
51
+ text: "bui-link--text bui-link--violet"
52
+ }
53
+ }
54
+
55
+ # Inizializzazione del componente
56
+ def initialize(
57
+ label:,
58
+ href: nil,
59
+ theme: :default,
60
+ icon: nil,
61
+ classes: nil,
62
+ active: false,
63
+ data: {},
64
+ method: nil,
65
+ target: nil
66
+ )
67
+ @label = label
68
+ @href = href
69
+ @theme = theme.to_sym
70
+ @icon = icon
71
+ @classes = classes
72
+ @active = active
73
+ @data = data || {}
74
+ @method = method
75
+ @target = target
76
+ end
77
+
78
+ # Determina se è un link attivo/corrente
79
+ def active?
80
+ @active
81
+ end
82
+
83
+ # Determina se è un link o solo testo
84
+ def link?
85
+ @href.present?
86
+ end
87
+
88
+ # Genera le classi per il componente
89
+ def component_classes
90
+ theme_classes = LINK_THEME.fetch(@theme, LINK_THEME[:default])
91
+
92
+ base_classes = ["bui-link"]
93
+
94
+ if active?
95
+ base_classes << theme_classes[:active]
96
+ elsif link?
97
+ base_classes << theme_classes[:link]
98
+ else
99
+ base_classes << theme_classes[:text]
100
+ end
101
+
102
+ base_classes << @classes if @classes.present?
103
+
104
+ base_classes.compact.join(" ")
105
+ end
106
+
107
+ # Restituisce gli attributi per il link
108
+ def link_attributes
109
+ attrs = {
110
+ class: component_classes
111
+ }
112
+
113
+ attrs[:data] = @data.merge(turbo_method: @method) if @method.present?
114
+ attrs[:data] = @data if @data.present? && !@method.present?
115
+ attrs[:target] = @target if @target.present?
116
+
117
+ attrs
118
+ end
119
+
120
+ # Renderizza l'icona
121
+ def render_icon
122
+ return nil unless @icon.present?
123
+
124
+ if @icon.is_a?(String)
125
+ render BetterUi::General::IconComponent.new(name: @icon)
126
+ else
127
+ @icon # Assumiamo che sia già un componente renderizzato
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -1,92 +1,87 @@
1
1
  module BetterUi
2
2
  module General
3
3
  class PanelComponent < ViewComponent::Base
4
- attr_reader :header, :footer, :body, :title, :padding, :variant
4
+ attr_reader :header, :footer, :body, :title, :padding, :variant, :rounded
5
5
 
6
- PADDING_OPTIONS = {
7
- none: '',
8
- small: 'p-2',
9
- medium: 'p-4',
10
- large: 'p-6'
6
+ # Opzioni di padding disponibili
7
+ PANEL_PADDING = {
8
+ none: 'bui-panel--padding-none',
9
+ small: 'bui-panel--padding-small',
10
+ medium: 'bui-panel--padding-medium',
11
+ large: 'bui-panel--padding-large'
11
12
  }.freeze
12
13
 
13
- def initialize(title: nil, body: nil, header: nil, footer: nil, padding: :medium, variant: :default)
14
+ # Temi di colore per il panel
15
+ PANEL_THEME = {
16
+ default: 'bui-panel--default',
17
+ white: 'bui-panel--white',
18
+ red: 'bui-panel--red',
19
+ rose: 'bui-panel--rose',
20
+ orange: 'bui-panel--orange',
21
+ green: 'bui-panel--green',
22
+ blue: 'bui-panel--blue',
23
+ yellow: 'bui-panel--yellow',
24
+ violet: 'bui-panel--violet'
25
+ }.freeze
26
+
27
+ # Opzioni di bordi arrotondati standardizzati
28
+ PANEL_RADIUS = {
29
+ none: 'bui-panel--radius-none',
30
+ small: 'bui-panel--radius-small',
31
+ medium: 'bui-panel--radius-medium',
32
+ large: 'bui-panel--radius-large',
33
+ full: 'bui-panel--radius-full'
34
+ }.freeze
35
+
36
+ def initialize(title: nil, body: nil, header: nil, footer: nil, padding: :medium, variant: :default, rounded: :small)
14
37
  @title = title
15
38
  @body = body
16
39
  @header = header
17
40
  @footer = footer
18
41
  @padding = padding.to_sym
19
42
  @variant = variant.to_sym
43
+ @rounded = rounded.to_sym
20
44
  end
21
45
 
22
46
  def panel_classes
23
- ThemeHelper.generate_component_classes(:panel, @variant)
47
+ [
48
+ 'bui-panel',
49
+ get_theme_class,
50
+ get_border_radius_class
51
+ ].compact.join(' ')
52
+ end
53
+
54
+ def get_border_radius_class
55
+ PANEL_RADIUS[@rounded] || PANEL_RADIUS[:small]
56
+ end
57
+
58
+ def get_theme_class
59
+ PANEL_THEME[@variant] || PANEL_THEME[:default]
24
60
  end
25
61
 
26
62
  def header_classes
27
63
  [
28
- 'panel-header',
29
- ThemeHelper::LAYOUT_STYLES[:panel][:header],
30
- header_color_classes,
31
- PADDING_OPTIONS.fetch(@padding, PADDING_OPTIONS[:medium])
64
+ 'bui-panel__header',
65
+ PANEL_PADDING.fetch(@padding, PANEL_PADDING[:medium])
32
66
  ].compact.join(' ')
33
67
  end
34
68
 
35
69
  def body_classes
36
70
  [
37
- 'panel-body',
38
- ThemeHelper::LAYOUT_STYLES[:panel][:body],
39
- 'overflow-x-auto break-words',
40
- PADDING_OPTIONS.fetch(@padding, PADDING_OPTIONS[:medium])
71
+ 'bui-panel__body',
72
+ PANEL_PADDING.fetch(@padding, PANEL_PADDING[:medium])
41
73
  ].compact.join(' ')
42
74
  end
43
75
 
44
76
  def footer_classes
45
77
  [
46
- 'panel-footer',
47
- ThemeHelper::LAYOUT_STYLES[:panel][:footer],
48
- footer_color_classes,
49
- 'overflow-x-auto break-words',
50
- PADDING_OPTIONS.fetch(@padding, PADDING_OPTIONS[:medium])
78
+ 'bui-panel__footer',
79
+ PANEL_PADDING.fetch(@padding, PANEL_PADDING[:medium])
51
80
  ].compact.join(' ')
52
81
  end
53
82
 
54
83
  def title_classes
55
- 'text-lg font-medium'
56
- end
57
-
58
- def header_color_classes
59
- case @variant
60
- when :primary
61
- 'bg-orange-50 text-orange-700'
62
- when :success
63
- 'bg-green-50 text-green-700'
64
- when :warning
65
- 'bg-amber-50 text-amber-700'
66
- when :danger
67
- 'bg-red-50 text-red-700'
68
- when :info
69
- 'bg-blue-50 text-blue-700'
70
- else
71
- 'bg-gray-50 text-gray-700'
72
- end
73
- end
74
-
75
- def footer_color_classes
76
- case @variant
77
- when :primary
78
- 'bg-orange-50 text-orange-600'
79
- when :success
80
- 'bg-green-50 text-green-600'
81
- when :warning
82
- 'bg-amber-50 text-amber-600'
83
- when :danger
84
- 'bg-red-50 text-red-600'
85
- when :info
86
- 'bg-blue-50 text-blue-600'
87
- else
88
- 'bg-gray-50 text-gray-600'
89
- end
84
+ 'bui-panel__title'
90
85
  end
91
86
 
92
87
  def render?
@@ -0,0 +1,15 @@
1
+ <div <%= spinner_attributes.to_s.html_safe %>>
2
+ <div class="bui-spinner__animation"></div>
3
+
4
+ <% if @label.present? %>
5
+ <div class="bui-spinner__label">
6
+ <%= @label %>
7
+ </div>
8
+ <% end %>
9
+
10
+ <% if content.present? %>
11
+ <div class="bui-spinner__content">
12
+ <%= content %>
13
+ </div>
14
+ <% end %>
15
+ </div>
@@ -0,0 +1,79 @@
1
+ module BetterUi
2
+ module General
3
+ class SpinnerComponent < ViewComponent::Base
4
+ attr_reader :size, :theme, :fullscreen, :label, :classes, :id
5
+
6
+ # Temi di colore disponibili
7
+ SPINNER_THEME = {
8
+ default: "bui-spinner--default",
9
+ white: "bui-spinner--white",
10
+ red: "bui-spinner--red",
11
+ rose: "bui-spinner--rose",
12
+ orange: "bui-spinner--orange",
13
+ green: "bui-spinner--green",
14
+ blue: "bui-spinner--blue",
15
+ yellow: "bui-spinner--yellow",
16
+ violet: "bui-spinner--violet"
17
+ }
18
+
19
+ # Dimensioni disponibili
20
+ SPINNER_SIZES = {
21
+ small: "bui-spinner--small",
22
+ medium: "bui-spinner--medium",
23
+ large: "bui-spinner--large"
24
+ }
25
+
26
+ # Stati e comportamenti dello spinner
27
+ SPINNER_STATES = {
28
+ fullscreen: "bui-spinner--fullscreen"
29
+ }
30
+
31
+ # Inizializzazione del componente
32
+ def initialize(
33
+ size: :medium,
34
+ theme: :default,
35
+ fullscreen: false,
36
+ label: nil,
37
+ classes: nil,
38
+ id: nil
39
+ )
40
+ @size = size.to_sym
41
+ @theme = theme.to_sym
42
+ @fullscreen = fullscreen
43
+ @label = label
44
+ @classes = classes
45
+ @id = id
46
+ end
47
+
48
+ # Combina tutte le classi
49
+ def combined_classes
50
+ [
51
+ "bui-spinner", # Classe base per tutti gli spinner
52
+ get_spinner_theme_class,
53
+ get_spinner_size_class,
54
+ @fullscreen ? SPINNER_STATES[:fullscreen] : "",
55
+ @classes
56
+ ].compact.join(" ")
57
+ end
58
+
59
+ def get_spinner_theme_class
60
+ SPINNER_THEME[@theme] || SPINNER_THEME[:default]
61
+ end
62
+
63
+ def get_spinner_size_class
64
+ SPINNER_SIZES[@size] || SPINNER_SIZES[:medium]
65
+ end
66
+
67
+ # Restituisce gli attributi per lo spinner
68
+ def spinner_attributes
69
+ attrs = {
70
+ class: combined_classes,
71
+ id: @id,
72
+ role: "status"
73
+ }
74
+
75
+ attrs
76
+ end
77
+ end
78
+ end
79
+ end
@@ -7,31 +7,67 @@
7
7
  <% end %>
8
8
 
9
9
  <thead class="<%= thead_classes %>">
10
- <tr>
11
- <% headers_for_display.each do |header| %>
12
- <th scope="col" class="<%= th_classes %>">
13
- <%= header.to_s.humanize %>
14
- </th>
15
- <% end %>
16
- </tr>
10
+ <% if header_rows_partial.present? %>
11
+ <%= render partial: header_rows_partial, locals: {
12
+ component: self,
13
+ headers: headers_for_display
14
+ } %>
15
+ <% else %>
16
+ <tr>
17
+ <% headers_for_display.each do |header| %>
18
+ <th scope="col" class="<%= th_classes %>">
19
+ <%= header.to_s.humanize %>
20
+ </th>
21
+ <% end %>
22
+ </tr>
23
+ <% end %>
17
24
  </thead>
18
25
 
19
26
  <tbody class="<%= tbody_classes %>">
20
27
  <% data.each_with_index do |row, index| %>
21
- <tr class="<%= tr_classes(index) %>">
22
- <% headers_for_display.each do |header| %>
23
- <td class="<%= td_classes %>">
24
- <% if row.is_a?(Hash) %>
25
- <%= row[header.to_s] || row[header.to_sym] %>
26
- <% elsif row.respond_to?(header.to_sym) %>
27
- <%= row.send(header.to_sym) %>
28
- <% else %>
29
-
30
- <% end %>
31
- </td>
32
- <% end %>
33
- </tr>
28
+ <% if body_row_partial.present? %>
29
+ <%= render partial: body_row_partial, locals: {
30
+ component: self,
31
+ row: row,
32
+ index: index,
33
+ headers: headers_for_display
34
+ } %>
35
+ <% else %>
36
+ <tr class="<%= tr_classes(index) %>">
37
+ <% headers_for_display.each do |header| %>
38
+ <td class="<%= td_classes %>">
39
+ <% if row.is_a?(Hash) %>
40
+ <%= row[header.to_s] || row[header.to_sym] %>
41
+ <% elsif row.respond_to?(header.to_sym) %>
42
+ <%= row.send(header.to_sym) %>
43
+ <% else %>
44
+
45
+ <% end %>
46
+ </td>
47
+ <% end %>
48
+ </tr>
49
+ <% end %>
34
50
  <% end %>
35
51
  </tbody>
52
+
53
+ <% if footer.present? %>
54
+ <tfoot class="<%= tfoot_classes %>">
55
+ <% if footer_rows_partial.present? %>
56
+ <%= render partial: footer_rows_partial, locals: {
57
+ component: self,
58
+ footer: footer,
59
+ headers: headers_for_display
60
+ } %>
61
+ <% else %>
62
+ <tr>
63
+ <% footer.each_with_index do |value, index| %>
64
+ <td class="<%= tf_classes %>">
65
+ <%= value || "—" %>
66
+ </td>
67
+ <% end %>
68
+ </tr>
69
+ <% end %>
70
+ </tfoot>
71
+ <% end %>
36
72
  </table>
37
73
  </div>
@@ -1,137 +1,139 @@
1
1
  module BetterUi
2
2
  module General
3
3
  class TableComponent < ViewComponent::Base
4
- attr_reader :data, :headers, :caption, :striped, :hoverable, :bordered, :compact, :classes, :variant
4
+ attr_reader :data, :headers, :caption, :striped, :hoverable, :bordered, :compact, :classes, :variant, :rounded, :footer,
5
+ :header_rows_partial, :body_row_partial, :footer_rows_partial
5
6
 
6
- def initialize(data:, headers: nil, caption: nil, striped: false, hoverable: false, bordered: true, compact: false, classes: nil, variant: :default)
7
+ # Costanti per configurazione stili
8
+ TABLE_THEMES = {
9
+ default: "bui-table--default",
10
+ white: "bui-table--white",
11
+ red: "bui-table--red",
12
+ rose: "bui-table--rose",
13
+ orange: "bui-table--orange",
14
+ green: "bui-table--green",
15
+ blue: "bui-table--blue",
16
+ yellow: "bui-table--yellow",
17
+ violet: "bui-table--violet"
18
+ }.freeze
19
+
20
+ # Opzioni di bordi arrotondati standardizzati
21
+ TABLE_RADIUS = {
22
+ none: "bui-table--radius-none",
23
+ small: "bui-table--radius-small",
24
+ medium: "bui-table--radius-medium",
25
+ large: "bui-table--radius-large",
26
+ full: "bui-table--radius-full"
27
+ }.freeze
28
+
29
+ def initialize(data:, headers: nil, caption: nil, striped: false, hoverable: false, bordered: true, compact: false, classes: nil, variant: :default, rounded: :small, footer: nil, header_rows_partial: nil, body_row_partial: nil, footer_rows_partial: nil)
7
30
  @data = data || []
8
31
  @headers = headers
9
32
  @caption = caption
10
- @striped = striped
11
- @hoverable = hoverable
12
- @bordered = bordered
13
- @compact = compact
33
+ @striped = !!striped
34
+ @hoverable = !!hoverable
35
+ @bordered = !!bordered
36
+ @compact = !!compact
14
37
  @classes = classes
15
- @variant = variant.to_sym
38
+ @variant = (TABLE_THEMES.key?(variant.to_sym) ? variant.to_sym : :default)
39
+ @rounded = (TABLE_RADIUS.key?(rounded.to_sym) ? rounded.to_sym : :small)
40
+ @footer = footer.is_a?(Array) ? footer : nil # Valida che sia un array
41
+ @header_rows_partial = header_rows_partial
42
+ @body_row_partial = body_row_partial
43
+ @footer_rows_partial = footer_rows_partial
16
44
  end
17
45
 
18
46
  def table_classes
19
- ThemeHelper.generate_component_classes(:table, @variant, { bordered: @bordered, classes: @classes })
47
+ [
48
+ "bui-table",
49
+ get_theme_class,
50
+ @bordered ? "bui-table--bordered" : nil,
51
+ @striped ? "bui-table--striped" : nil,
52
+ @hoverable ? "bui-table--hoverable" : nil,
53
+ @compact ? "bui-table--compact" : nil,
54
+ @classes
55
+ ].compact.join(" ")
20
56
  end
21
57
 
22
58
  def table_container_classes
23
59
  [
24
- ThemeHelper::LAYOUT_STYLES[:table][:container],
25
- get_border_color
26
- ].compact.join(' ')
60
+ "bui-table__container",
61
+ get_border_radius_class
62
+ ].compact.join(" ")
63
+ end
64
+
65
+ def get_border_radius_class
66
+ TABLE_RADIUS[@rounded] || TABLE_RADIUS[:small]
67
+ end
68
+
69
+ def get_theme_class
70
+ TABLE_THEMES[@variant] || TABLE_THEMES[:default]
27
71
  end
28
72
 
29
73
  def caption_classes
30
- [
31
- 'px-4 py-2',
32
- 'text-sm font-medium text-left',
33
- caption_color_classes,
34
- @bordered ? "border-b #{get_border_color}" : nil
35
- ].compact.join(' ')
74
+ "bui-table__caption"
36
75
  end
37
76
 
38
77
  def thead_classes
39
- ThemeHelper::LAYOUT_STYLES[:table][:header]
78
+ "bui-table__header"
40
79
  end
41
80
 
42
81
  def tbody_classes
43
- @striped ? ThemeHelper::LAYOUT_STYLES[:table][:row][:striped] : nil
82
+ "bui-table__body"
83
+ end
84
+
85
+ def tfoot_classes
86
+ "bui-table__footer"
44
87
  end
45
88
 
46
89
  def tr_classes(index)
47
- [
48
- @hoverable ? ThemeHelper::LAYOUT_STYLES[:table][:row][:hover] : nil,
49
- @striped ? nil : (index.odd? ? 'bg-gray-50' : nil)
50
- ].compact.join(' ')
90
+ "bui-table__row"
51
91
  end
52
92
 
53
93
  def th_classes
54
94
  [
55
- @compact ? 'px-2 py-1' : 'px-4 py-3',
56
- 'text-left text-xs font-medium uppercase tracking-wider',
57
- th_color_classes,
58
- @bordered ? "border #{get_border_color}" : nil
59
- ].compact.join(' ')
95
+ "bui-table__cell",
96
+ "bui-table__cell--header"
97
+ ].compact.join(" ")
60
98
  end
61
99
 
62
100
  def td_classes
63
- [
64
- @compact ? 'px-2 py-1' : 'px-4 py-3',
65
- @bordered ? "border #{get_border_color}" : nil,
66
- 'text-sm'
67
- ].compact.join(' ')
101
+ "bui-table__cell"
68
102
  end
69
103
 
70
- def get_border_color
71
- case @variant
72
- when :primary
73
- 'border-orange-200'
74
- when :success
75
- 'border-green-200'
76
- when :warning
77
- 'border-amber-200'
78
- when :danger
79
- 'border-red-200'
80
- when :info
81
- 'border-blue-200'
82
- else
83
- 'border-gray-200'
84
- end
85
- end
86
-
87
- def caption_color_classes
88
- case @variant
89
- when :primary
90
- 'bg-orange-50 text-orange-700'
91
- when :success
92
- 'bg-green-50 text-green-700'
93
- when :warning
94
- 'bg-amber-50 text-amber-700'
95
- when :danger
96
- 'bg-red-50 text-red-700'
97
- when :info
98
- 'bg-blue-50 text-blue-700'
99
- else
100
- 'bg-gray-50 text-gray-700'
101
- end
102
- end
103
-
104
- def th_color_classes
105
- case @variant
106
- when :primary
107
- 'text-orange-700'
108
- when :success
109
- 'text-green-700'
110
- when :warning
111
- 'text-amber-700'
112
- when :danger
113
- 'text-red-700'
114
- when :info
115
- 'text-blue-700'
116
- else
117
- 'text-gray-700'
118
- end
104
+ def tf_classes
105
+ [
106
+ "bui-table__cell",
107
+ "bui-table__cell--footer"
108
+ ].compact.join(" ")
119
109
  end
120
110
 
121
111
  def headers_for_display
122
112
  return @headers if @headers.present?
123
113
  return [] if @data.empty?
124
114
 
125
- # Se non sono stati forniti headers, li derivo dalle chiavi del primo elemento
126
- first_item = @data.first
127
- if first_item.is_a?(Hash)
115
+ case first_item = @data.first
116
+ when Hash
128
117
  first_item.keys
129
- elsif first_item.respond_to?(:attributes)
130
- first_item.attributes.keys - ['id', 'created_at', 'updated_at']
118
+ when -> (item) { item.respond_to?(:attributes) }
119
+ first_item.attributes.keys - %w[id created_at updated_at]
131
120
  else
132
121
  []
133
122
  end
134
123
  end
124
+
125
+ # Ottiene il valore di una cella in modo consistente
126
+ def get_cell_value(row, header)
127
+ if row.is_a?(Hash)
128
+ row[header.to_s] || row[header.to_sym] || "—"
129
+ elsif row.respond_to?(header.to_sym)
130
+ row.send(header.to_sym)
131
+ elsif row.is_a?(Array) && headers_for_display.index(header)
132
+ row[headers_for_display.index(header)] || "—"
133
+ else
134
+ "—"
135
+ end
136
+ end
135
137
 
136
138
  def render?
137
139
  @data.present?