better_ui 0.6.0 → 0.7.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 (198) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +257 -212
  3. data/Rakefile +11 -2
  4. data/app/components/better_ui/action_messages_component/action_messages_component.html.erb +48 -0
  5. data/app/components/better_ui/action_messages_component.rb +544 -0
  6. data/app/components/better_ui/application_component.rb +66 -0
  7. data/app/components/better_ui/button_component/button_component.html.erb +31 -0
  8. data/app/components/better_ui/button_component.rb +307 -0
  9. data/app/components/better_ui/card_component/card_component.html.erb +17 -0
  10. data/app/components/better_ui/card_component.rb +460 -0
  11. data/app/components/better_ui/drawer/header_component/header_component.html.erb +24 -0
  12. data/app/components/better_ui/drawer/header_component.rb +238 -0
  13. data/app/components/better_ui/drawer/layout_component/layout_component.html.erb +44 -0
  14. data/app/components/better_ui/drawer/layout_component.rb +270 -0
  15. data/app/components/better_ui/drawer/nav_group_component/nav_group_component.html.erb +10 -0
  16. data/app/components/better_ui/drawer/nav_group_component.rb +155 -0
  17. data/app/components/better_ui/drawer/nav_item_component/nav_item_component.html.erb +13 -0
  18. data/app/components/better_ui/drawer/nav_item_component.rb +225 -0
  19. data/app/components/better_ui/drawer/sidebar_component/sidebar_component.html.erb +17 -0
  20. data/app/components/better_ui/drawer/sidebar_component.rb +263 -0
  21. data/app/components/better_ui/forms/base_component.rb +450 -0
  22. data/app/components/better_ui/forms/checkbox_component/checkbox_component.html.erb +28 -0
  23. data/app/components/better_ui/forms/checkbox_component.rb +419 -0
  24. data/app/components/better_ui/forms/checkbox_group_component/checkbox_group_component.html.erb +40 -0
  25. data/app/components/better_ui/forms/checkbox_group_component.rb +363 -0
  26. data/app/components/better_ui/forms/number_input_component/number_input_component.html.erb +40 -0
  27. data/app/components/better_ui/forms/number_input_component.rb +320 -0
  28. data/app/components/better_ui/forms/password_input_component/password_input_component.html.erb +71 -0
  29. data/app/components/better_ui/forms/password_input_component.rb +206 -0
  30. data/app/components/better_ui/forms/text_input_component/text_input_component.html.erb +40 -0
  31. data/app/components/better_ui/forms/text_input_component.rb +258 -0
  32. data/app/components/better_ui/forms/textarea_component/textarea_component.html.erb +40 -0
  33. data/app/components/better_ui/forms/textarea_component.rb +329 -0
  34. data/app/form_builders/better_ui/ui_form_builder.rb +467 -0
  35. data/app/helpers/better_ui/application_helper.rb +325 -58
  36. data/app/views/layouts/better_ui/application.html.erb +1 -1
  37. data/config/routes.rb +1 -0
  38. data/lib/better_ui/engine.rb +34 -5
  39. data/lib/better_ui/version.rb +1 -1
  40. data/lib/better_ui.rb +32 -5
  41. data/lib/generators/better_ui/install/USAGE +44 -0
  42. data/lib/generators/better_ui/install/install_generator.rb +87 -0
  43. data/lib/generators/better_ui/install/templates/better_ui_theme.css.tt +280 -0
  44. data/lib/tasks/better_ui_tasks.rake +39 -4
  45. metadata +55 -203
  46. data/app/components/better_ui/application/card/component.html.erb +0 -20
  47. data/app/components/better_ui/application/card/component.rb +0 -214
  48. data/app/components/better_ui/application/main/component.html.erb +0 -9
  49. data/app/components/better_ui/application/main/component.rb +0 -123
  50. data/app/components/better_ui/application/navbar/component.html.erb +0 -92
  51. data/app/components/better_ui/application/navbar/component.rb +0 -136
  52. data/app/components/better_ui/application/sidebar/component.html.erb +0 -249
  53. data/app/components/better_ui/application/sidebar/component.rb +0 -187
  54. data/app/components/better_ui/general/accordion/component.html.erb +0 -5
  55. data/app/components/better_ui/general/accordion/component.rb +0 -92
  56. data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
  57. data/app/components/better_ui/general/accordion/item_component.rb +0 -176
  58. data/app/components/better_ui/general/alert/component.html.erb +0 -32
  59. data/app/components/better_ui/general/alert/component.rb +0 -242
  60. data/app/components/better_ui/general/avatar/component.html.erb +0 -20
  61. data/app/components/better_ui/general/avatar/component.rb +0 -301
  62. data/app/components/better_ui/general/badge/component.html.erb +0 -23
  63. data/app/components/better_ui/general/badge/component.rb +0 -248
  64. data/app/components/better_ui/general/breadcrumb/component.html.erb +0 -15
  65. data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
  66. data/app/components/better_ui/general/button/component.html.erb +0 -34
  67. data/app/components/better_ui/general/button/component.rb +0 -214
  68. data/app/components/better_ui/general/divider/component.html.erb +0 -10
  69. data/app/components/better_ui/general/divider/component.rb +0 -226
  70. data/app/components/better_ui/general/dropdown/component.html.erb +0 -28
  71. data/app/components/better_ui/general/dropdown/component.rb +0 -192
  72. data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
  73. data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
  74. data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
  75. data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
  76. data/app/components/better_ui/general/field/component.html.erb +0 -27
  77. data/app/components/better_ui/general/field/component.rb +0 -37
  78. data/app/components/better_ui/general/grid/cell_component.html.erb +0 -3
  79. data/app/components/better_ui/general/grid/cell_component.rb +0 -390
  80. data/app/components/better_ui/general/grid/component.html.erb +0 -3
  81. data/app/components/better_ui/general/grid/component.rb +0 -301
  82. data/app/components/better_ui/general/heading/component.html.erb +0 -22
  83. data/app/components/better_ui/general/heading/component.rb +0 -257
  84. data/app/components/better_ui/general/icon/component.html.erb +0 -7
  85. data/app/components/better_ui/general/icon/component.rb +0 -240
  86. data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
  87. data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
  88. data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
  89. data/app/components/better_ui/general/input/datetime/component.rb +0 -223
  90. data/app/components/better_ui/general/input/pin/component.html.erb +0 -1
  91. data/app/components/better_ui/general/input/pin/component.rb +0 -201
  92. data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
  93. data/app/components/better_ui/general/input/radio/component.rb +0 -230
  94. data/app/components/better_ui/general/input/rating/component.html.erb +0 -4
  95. data/app/components/better_ui/general/input/rating/component.rb +0 -272
  96. data/app/components/better_ui/general/input/select/component.html.erb +0 -78
  97. data/app/components/better_ui/general/input/select/component.rb +0 -249
  98. data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
  99. data/app/components/better_ui/general/input/select/select_component.rb +0 -37
  100. data/app/components/better_ui/general/input/text/component.html.erb +0 -5
  101. data/app/components/better_ui/general/input/text/component.rb +0 -171
  102. data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
  103. data/app/components/better_ui/general/input/textarea/component.rb +0 -166
  104. data/app/components/better_ui/general/input/toggle/component.html.erb +0 -5
  105. data/app/components/better_ui/general/input/toggle/component.rb +0 -242
  106. data/app/components/better_ui/general/link/component.html.erb +0 -18
  107. data/app/components/better_ui/general/link/component.rb +0 -258
  108. data/app/components/better_ui/general/modal/component.html.erb +0 -5
  109. data/app/components/better_ui/general/modal/component.rb +0 -47
  110. data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
  111. data/app/components/better_ui/general/modal/modal_component.rb +0 -160
  112. data/app/components/better_ui/general/pagination/component.html.erb +0 -85
  113. data/app/components/better_ui/general/pagination/component.rb +0 -216
  114. data/app/components/better_ui/general/panel/component.html.erb +0 -28
  115. data/app/components/better_ui/general/panel/component.rb +0 -249
  116. data/app/components/better_ui/general/progress/component.html.erb +0 -11
  117. data/app/components/better_ui/general/progress/component.rb +0 -160
  118. data/app/components/better_ui/general/spinner/component.html.erb +0 -35
  119. data/app/components/better_ui/general/spinner/component.rb +0 -93
  120. data/app/components/better_ui/general/table/component.html.erb +0 -5
  121. data/app/components/better_ui/general/table/component.rb +0 -217
  122. data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
  123. data/app/components/better_ui/general/table/tbody_component.rb +0 -30
  124. data/app/components/better_ui/general/table/td_component.html.erb +0 -3
  125. data/app/components/better_ui/general/table/td_component.rb +0 -44
  126. data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
  127. data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
  128. data/app/components/better_ui/general/table/th_component.html.erb +0 -6
  129. data/app/components/better_ui/general/table/th_component.rb +0 -51
  130. data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
  131. data/app/components/better_ui/general/table/thead_component.rb +0 -28
  132. data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
  133. data/app/components/better_ui/general/table/tr_component.rb +0 -30
  134. data/app/components/better_ui/general/tabs/component.html.erb +0 -11
  135. data/app/components/better_ui/general/tabs/component.rb +0 -120
  136. data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
  137. data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
  138. data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
  139. data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
  140. data/app/components/better_ui/general/tag/component.html.erb +0 -3
  141. data/app/components/better_ui/general/tag/component.rb +0 -104
  142. data/app/components/better_ui/general/text/component.html.erb +0 -1
  143. data/app/components/better_ui/general/text/component.rb +0 -194
  144. data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
  145. data/app/components/better_ui/general/tooltip/component.rb +0 -239
  146. data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
  147. data/app/helpers/better_ui/application/components/card.rb +0 -11
  148. data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
  149. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
  150. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
  151. data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
  152. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
  153. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
  154. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
  155. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
  156. data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
  157. data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
  158. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
  159. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
  160. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -88
  161. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -68
  162. data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
  163. data/app/helpers/better_ui/general/components/grid/grid_helper.rb +0 -145
  164. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
  165. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
  166. data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
  167. data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
  168. data/app/helpers/better_ui/general/components/input/pin/pin_helper.rb +0 -76
  169. data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
  170. data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
  171. data/app/helpers/better_ui/general/components/input/rating/rating_helper.rb +0 -70
  172. data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -86
  173. data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
  174. data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
  175. data/app/helpers/better_ui/general/components/input/toggle/toggle_helper.rb +0 -77
  176. data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
  177. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
  178. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
  179. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
  180. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
  181. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
  182. data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
  183. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
  184. data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
  185. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
  186. data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
  187. data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
  188. data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
  189. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
  190. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
  191. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
  192. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
  193. data/app/helpers/better_ui/general/components/text/text_helper.rb +0 -83
  194. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
  195. data/app/jobs/better_ui/application_job.rb +0 -4
  196. data/app/mailers/better_ui/application_mailer.rb +0 -6
  197. data/config/initializers/lookbook.rb +0 -23
  198. data/lib/better_ui/railtie.rb +0 -20
@@ -1,217 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class Component < ViewComponent::Base
5
- attr_reader :data, :headers, :caption, :striped, :hoverable, :bordered, :compact, :minimal, :footer,
6
- :header_rows_partial, :body_row_partial, :footer_rows_partial, :thead_partial, :tfoot_partial
7
-
8
- # Classi base sempre presenti
9
- TABLE_BASE_CLASSES = "w-full table-auto border-collapse"
10
-
11
- # Temi di colore con classi Tailwind dirette
12
- TABLE_THEME = {
13
- default: "bg-gray-50 text-gray-900",
14
- white: "bg-white text-gray-900",
15
- red: "bg-red-50 text-red-900",
16
- rose: "bg-rose-50 text-rose-900",
17
- orange: "bg-orange-50 text-orange-900",
18
- green: "bg-green-50 text-green-900",
19
- blue: "bg-blue-50 text-blue-900",
20
- yellow: "bg-yellow-50 text-yellow-900",
21
- violet: "bg-violet-50 text-violet-900"
22
- }.freeze
23
-
24
- # Opzioni di bordi arrotondati con classi Tailwind dirette
25
- TABLE_RADIUS = {
26
- none: "rounded-none",
27
- small: "rounded-md",
28
- medium: "rounded-lg",
29
- large: "rounded-xl",
30
- full: "rounded-full"
31
- }.freeze
32
-
33
-
34
- # Classi per container
35
- CONTAINER_BASE_CLASSES = "overflow-x-auto"
36
-
37
- # Classi per elementi della tabella
38
- THEAD_CLASSES = "bg-gray-100 border-b border-gray-200"
39
- TBODY_CLASSES = ""
40
- TFOOT_CLASSES = "bg-gray-50 border-t border-gray-200"
41
- TR_CLASSES = "border-b border-gray-100 hover:bg-gray-50"
42
- TH_CLASSES = "px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
43
- TD_CLASSES = "px-4 py-3 text-sm text-gray-900"
44
- TF_CLASSES = "px-4 py-3 text-sm font-medium text-gray-900"
45
- CAPTION_CLASSES = "mb-2 text-sm text-gray-600 text-left"
46
-
47
- def initialize(
48
- data: nil,
49
- headers: nil,
50
- caption: nil,
51
- theme: :default,
52
- radius: :small,
53
- striped: false,
54
- hoverable: false,
55
- bordered: false,
56
- compact: false,
57
- minimal: false,
58
- footer: nil,
59
- header_rows_partial: nil,
60
- body_row_partial: nil,
61
- footer_rows_partial: nil,
62
- thead_partial: nil,
63
- tfoot_partial: nil,
64
- **html_options
65
- )
66
- @data = data || []
67
- @headers = headers
68
- @caption = caption
69
- @theme = theme.to_sym
70
- @radius = radius.to_sym
71
- # Flag boolean combinabili
72
- @striped = !!striped
73
- @hoverable = !!hoverable
74
- @bordered = !!bordered
75
- @compact = !!compact
76
- @minimal = !!minimal
77
- @footer = footer.is_a?(Array) ? footer : nil
78
- @header_rows_partial = header_rows_partial
79
- @body_row_partial = body_row_partial
80
- @footer_rows_partial = footer_rows_partial
81
- @thead_partial = thead_partial
82
- @tfoot_partial = tfoot_partial
83
- @html_options = html_options
84
-
85
- validate_params
86
- end
87
-
88
- # Combina tutte le classi per la tabella
89
- def combined_classes
90
- [
91
- TABLE_BASE_CLASSES,
92
- get_theme_class,
93
- @bordered ? "border border-gray-200" : nil,
94
- @striped ? "[&_tbody_tr:nth-child(odd)]:bg-gray-50" : nil,
95
- @hoverable ? "[&_tbody_tr]:hover:bg-gray-50" : nil,
96
- @compact ? "[&_td]:py-1 [&_th]:py-1" : nil,
97
- @minimal ? "border-0" : nil,
98
- @html_options[:class]
99
- ].compact.join(" ")
100
- end
101
-
102
- # Restituisce gli attributi HTML per la tabella
103
- def table_attributes
104
- attrs = @html_options.except(:class)
105
- attrs[:class] = combined_classes
106
- attrs
107
- end
108
-
109
- # Combina le classi per il container
110
- def table_container_classes
111
- [
112
- CONTAINER_BASE_CLASSES,
113
- get_radius_class
114
- ].compact.join(" ")
115
- end
116
-
117
- # Restituisce gli attributi HTML per il container
118
- def container_attributes
119
- {
120
- class: table_container_classes
121
- }
122
- end
123
-
124
- def get_radius_class
125
- TABLE_RADIUS[@radius] || TABLE_RADIUS[:small]
126
- end
127
-
128
- def get_theme_class
129
- TABLE_THEME[@theme] || TABLE_THEME[:default]
130
- end
131
-
132
-
133
- def caption_classes
134
- CAPTION_CLASSES
135
- end
136
-
137
- def thead_classes
138
- THEAD_CLASSES
139
- end
140
-
141
- def tbody_classes
142
- TBODY_CLASSES
143
- end
144
-
145
- def tfoot_classes
146
- TFOOT_CLASSES
147
- end
148
-
149
- def tr_classes(index)
150
- TR_CLASSES
151
- end
152
-
153
- def th_classes
154
- TH_CLASSES
155
- end
156
-
157
- def td_classes
158
- TD_CLASSES
159
- end
160
-
161
- def tf_classes
162
- TF_CLASSES
163
- end
164
-
165
- def headers_for_display
166
- return @headers if @headers.present?
167
- return [] if @data.empty?
168
-
169
- case first_item = @data.first
170
- when Hash
171
- first_item.keys
172
- when ->(item) { item.respond_to?(:attributes) }
173
- first_item.attributes.keys - %w[id created_at updated_at]
174
- else
175
- []
176
- end
177
- end
178
-
179
- # Ottiene il valore di una cella in modo consistente
180
- def get_cell_value(row, header)
181
- if row.is_a?(Hash)
182
- row[header.to_s] || row[header.to_sym] || "—"
183
- elsif row.respond_to?(header.to_sym)
184
- row.send(header.to_sym)
185
- elsif row.is_a?(Array) && headers_for_display.index(header)
186
- row[headers_for_display.index(header)] || "—"
187
- else
188
- "—"
189
- end
190
- end
191
-
192
- def render?
193
- true
194
- end
195
-
196
- private
197
-
198
- def validate_params
199
- validate_theme
200
- validate_radius
201
- end
202
-
203
- def validate_theme
204
- unless TABLE_THEME.keys.include?(@theme)
205
- raise ArgumentError, "Il tema deve essere uno tra: #{TABLE_THEME.keys.join(', ')}"
206
- end
207
- end
208
-
209
- def validate_radius
210
- unless TABLE_RADIUS.keys.include?(@radius)
211
- raise ArgumentError, "Il radius deve essere uno tra: #{TABLE_RADIUS.keys.join(', ')}"
212
- end
213
- end
214
- end
215
- end
216
- end
217
- end
@@ -1,3 +0,0 @@
1
- <tbody <%= tag.attributes(tbody_attributes) %>>
2
- <%= content %>
3
- </tbody>
@@ -1,30 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class TbodyComponent < ViewComponent::Base
5
- attr_reader :theme, :striped, :hoverable
6
-
7
- def initialize(theme: :default, striped: false, hoverable: false, **html_options)
8
- @theme = theme.to_sym
9
- @striped = !!striped
10
- @hoverable = !!hoverable
11
- @html_options = html_options
12
- end
13
-
14
- def tbody_classes
15
- [
16
- @striped ? "[&_tr:nth-child(odd)]:bg-gray-50" : nil,
17
- @hoverable ? "[&_tr]:hover:bg-gray-50" : nil,
18
- @html_options[:class]
19
- ].compact.join(" ")
20
- end
21
-
22
- def tbody_attributes
23
- attrs = @html_options.except(:class)
24
- attrs[:class] = tbody_classes
25
- attrs
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,3 +0,0 @@
1
- <td <%= tag.attributes(td_attributes) %>>
2
- <%= content %>
3
- </td>
@@ -1,44 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class TdComponent < ViewComponent::Base
5
- attr_reader :theme, :align, :compact
6
-
7
- def initialize(theme: :default, align: :left, compact: false, **html_options)
8
- @theme = theme.to_sym
9
- @align = align.to_sym
10
- @compact = !!compact
11
- @html_options = html_options
12
- end
13
-
14
- def td_classes
15
- [
16
- "px-4 py-3 text-sm text-gray-900",
17
- alignment_class,
18
- @compact ? "py-1" : nil,
19
- @html_options[:class]
20
- ].compact.join(" ")
21
- end
22
-
23
- def td_attributes
24
- attrs = @html_options.except(:class)
25
- attrs[:class] = td_classes
26
- attrs
27
- end
28
-
29
- private
30
-
31
- def alignment_class
32
- case @align
33
- when :center
34
- "text-center"
35
- when :right
36
- "text-right"
37
- else
38
- "text-left"
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,3 +0,0 @@
1
- <tfoot <%= tag.attributes(tfoot_attributes) %>>
2
- <%= content %>
3
- </tfoot>
@@ -1,28 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class TfootComponent < ViewComponent::Base
5
- attr_reader :theme, :bordered
6
-
7
- def initialize(theme: :default, bordered: false, **html_options)
8
- @theme = theme.to_sym
9
- @bordered = !!bordered
10
- @html_options = html_options
11
- end
12
-
13
- def tfoot_classes
14
- [
15
- "bg-gray-50 border-t border-gray-200",
16
- @html_options[:class]
17
- ].compact.join(" ")
18
- end
19
-
20
- def tfoot_attributes
21
- attrs = @html_options.except(:class)
22
- attrs[:class] = tfoot_classes
23
- attrs
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,6 +0,0 @@
1
- <th <%= tag.attributes(th_attributes) %>>
2
- <%= content %>
3
- <% if @sortable %>
4
- <span class="ml-1 text-gray-400"><%= sort_icon %></span>
5
- <% end %>
6
- </th>
@@ -1,51 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class ThComponent < ViewComponent::Base
5
- attr_reader :theme, :sortable, :sorted, :sort_direction, :scope
6
-
7
- def initialize(
8
- theme: :default,
9
- sortable: false,
10
- sorted: false,
11
- sort_direction: :asc,
12
- scope: "col",
13
- **html_options
14
- )
15
- @theme = theme.to_sym
16
- @sortable = !!sortable
17
- @sorted = !!sorted
18
- @sort_direction = sort_direction.to_sym
19
- @scope = scope
20
- @html_options = html_options
21
- end
22
-
23
- def th_classes
24
- [
25
- "px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",
26
- @sortable ? "cursor-pointer hover:bg-gray-200" : nil,
27
- @sorted ? "bg-gray-200" : nil,
28
- @html_options[:class]
29
- ].compact.join(" ")
30
- end
31
-
32
- def th_attributes
33
- attrs = @html_options.except(:class)
34
- attrs[:class] = th_classes
35
- attrs[:scope] = @scope
36
- attrs
37
- end
38
-
39
- def sort_icon
40
- return unless @sortable
41
-
42
- if @sorted
43
- @sort_direction == :asc ? "↑" : "↓"
44
- else
45
- "↕"
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,3 +0,0 @@
1
- <thead <%= tag.attributes(thead_attributes) %>>
2
- <%= content %>
3
- </thead>
@@ -1,28 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class TheadComponent < ViewComponent::Base
5
- attr_reader :theme, :bordered
6
-
7
- def initialize(theme: :default, bordered: false, **html_options)
8
- @theme = theme.to_sym
9
- @bordered = !!bordered
10
- @html_options = html_options
11
- end
12
-
13
- def thead_classes
14
- [
15
- "bg-gray-100 border-b border-gray-200",
16
- @html_options[:class]
17
- ].compact.join(" ")
18
- end
19
-
20
- def thead_attributes
21
- attrs = @html_options.except(:class)
22
- attrs[:class] = thead_classes
23
- attrs
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,3 +0,0 @@
1
- <tr <%= tag.attributes(tr_attributes) %>>
2
- <%= content %>
3
- </tr>
@@ -1,30 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Table
4
- class TrComponent < ViewComponent::Base
5
- attr_reader :theme, :highlighted, :striped_index
6
-
7
- def initialize(theme: :default, highlighted: false, striped_index: nil, **html_options)
8
- @theme = theme.to_sym
9
- @highlighted = !!highlighted
10
- @striped_index = striped_index
11
- @html_options = html_options
12
- end
13
-
14
- def tr_classes
15
- [
16
- "border-b border-gray-100",
17
- @highlighted ? "bg-blue-50" : nil,
18
- @html_options[:class]
19
- ].compact.join(" ")
20
- end
21
-
22
- def tr_attributes
23
- attrs = @html_options.except(:class)
24
- attrs[:class] = tr_classes
25
- attrs
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,11 +0,0 @@
1
- <div <%= tag.attributes(wrapper_attributes) %>>
2
- <!-- Navigation Tabs -->
3
- <div <%= tag.attributes(navigation_attributes) %>>
4
- <%= navigation %>
5
- </div>
6
-
7
- <!-- Tab Panels -->
8
- <div <%= tag.attributes(panels_attributes) %>>
9
- <%= panels %>
10
- </div>
11
- </div>
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Tabs
6
- class Component < ViewComponent::Base
7
- renders_one :navigation
8
- renders_one :panels
9
- TABS_VARIANT = {
10
- pills: 'bg-gray-100 rounded-lg p-1',
11
- underline: 'border-b border-gray-200',
12
- bordered: 'border border-gray-200 rounded-lg',
13
- minimal: ''
14
- }.freeze
15
-
16
- TABS_THEME_DEFAULT = {
17
- default: 'text-gray-600',
18
- blue: 'text-blue-600',
19
- red: 'text-red-600',
20
- green: 'text-green-600',
21
- yellow: 'text-yellow-600',
22
- violet: 'text-violet-600',
23
- orange: 'text-orange-600',
24
- rose: 'text-rose-600',
25
- white: 'text-white'
26
- }.freeze
27
-
28
- TABS_SIZE = {
29
- small: 'text-sm',
30
- medium: 'text-base',
31
- large: 'text-lg'
32
- }.freeze
33
-
34
- TABS_ORIENTATION = {
35
- horizontal: 'flex-row',
36
- vertical: 'flex-col'
37
- }.freeze
38
-
39
- def initialize(variant: :pills, theme: :default, size: :medium, orientation: :horizontal,
40
- navigation_classes: '', panels_classes: 'mt-4', **options)
41
- @variant = variant
42
- @theme = theme
43
- @size = size
44
- @orientation = orientation
45
- @navigation_classes = navigation_classes
46
- @panels_classes = panels_classes
47
- @options = options
48
-
49
- validate_params
50
- end
51
-
52
- private
53
-
54
- attr_reader :variant, :theme, :size, :orientation, :navigation_classes, :panels_classes, :options
55
-
56
- def validate_params
57
- validate_variant
58
- validate_theme
59
- validate_size
60
- validate_orientation
61
- end
62
-
63
- def validate_variant
64
- return if TABS_VARIANT.key?(variant)
65
-
66
- raise ArgumentError, "Invalid variant: #{variant}. Must be one of #{TABS_VARIANT.keys}"
67
- end
68
-
69
- def validate_theme
70
- return if TABS_THEME_DEFAULT.key?(theme)
71
-
72
- raise ArgumentError, "Invalid theme: #{theme}. Must be one of #{TABS_THEME_DEFAULT.keys}"
73
- end
74
-
75
- def validate_size
76
- return if TABS_SIZE.key?(size)
77
-
78
- raise ArgumentError, "Invalid size: #{size}. Must be one of #{TABS_SIZE.keys}"
79
- end
80
-
81
- def validate_orientation
82
- return if TABS_ORIENTATION.key?(orientation)
83
-
84
- raise ArgumentError, "Invalid orientation: #{orientation}. Must be one of #{TABS_ORIENTATION.keys}"
85
- end
86
-
87
- # Attributi per il wrapper principale (con data-controller)
88
- def wrapper_attributes
89
- {
90
- 'data-controller': 'bui-tabs'
91
- }.merge(options)
92
- end
93
-
94
- # Attributi per il container della navigazione tabs
95
- def navigation_attributes
96
- base_classes = [
97
- 'flex',
98
- TABS_ORIENTATION[orientation],
99
- TABS_VARIANT[variant],
100
- TABS_THEME_DEFAULT[theme],
101
- TABS_SIZE[size],
102
- navigation_classes
103
- ].compact.join(' ')
104
-
105
- {
106
- class: base_classes,
107
- role: 'tablist'
108
- }
109
- end
110
-
111
- # Attributi per il container dei panel
112
- def panels_attributes
113
- {
114
- class: panels_classes
115
- }
116
- end
117
- end
118
- end
119
- end
120
- end
@@ -1,3 +0,0 @@
1
- <div <%= tag.attributes(panel_attributes) %>>
2
- <%= content %>
3
- </div>
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Tabs
6
- class PanelComponent < ViewComponent::Base
7
- def initialize(id:, active: false, classes: '', **options)
8
- @id = id
9
- @active = active
10
- @classes = classes
11
- @options = options
12
- end
13
-
14
- private
15
-
16
- attr_reader :id, :active, :classes, :options
17
-
18
- def panel_attributes
19
- base_classes = [
20
- 'focus:outline-none',
21
- 'hidden', # Sempre nascosto inizialmente, JavaScript gestisce la visibilità
22
- classes
23
- ].compact.join(' ')
24
-
25
- {
26
- class: base_classes,
27
- role: 'tabpanel',
28
- id: id,
29
- 'aria-labelledby': "tab-#{id}",
30
- 'data-bui-tabs-target': 'panel',
31
- tabindex: '0'
32
- }.merge(options)
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,13 +0,0 @@
1
- <button <%= tag.attributes(tab_attributes) %>>
2
- <% if has_icon? %>
3
- <%= bui_icon(name: icon, classes: 'w-5 h-5') %>
4
- <% end %>
5
-
6
- <span><%= text %></span>
7
-
8
- <% if has_badge? %>
9
- <span class="ml-2 bg-red-100 text-red-800 text-xs font-medium px-2 py-0.5 rounded-full">
10
- <%= badge %>
11
- </span>
12
- <% end %>
13
- </button>