better_ui 0.3.0 → 0.7.0

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 (183) 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 -51
  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 -4
  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 +52 -185
  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 -227
  53. data/app/components/better_ui/application/sidebar/component.rb +0 -130
  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 -25
  71. data/app/components/better_ui/general/dropdown/component.rb +0 -170
  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/heading/component.html.erb +0 -22
  79. data/app/components/better_ui/general/heading/component.rb +0 -257
  80. data/app/components/better_ui/general/icon/component.html.erb +0 -7
  81. data/app/components/better_ui/general/icon/component.rb +0 -239
  82. data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
  83. data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
  84. data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
  85. data/app/components/better_ui/general/input/datetime/component.rb +0 -223
  86. data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
  87. data/app/components/better_ui/general/input/radio/component.rb +0 -230
  88. data/app/components/better_ui/general/input/select/component.html.erb +0 -16
  89. data/app/components/better_ui/general/input/select/component.rb +0 -184
  90. data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
  91. data/app/components/better_ui/general/input/select/select_component.rb +0 -37
  92. data/app/components/better_ui/general/input/text/component.html.erb +0 -5
  93. data/app/components/better_ui/general/input/text/component.rb +0 -171
  94. data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
  95. data/app/components/better_ui/general/input/textarea/component.rb +0 -166
  96. data/app/components/better_ui/general/link/component.html.erb +0 -18
  97. data/app/components/better_ui/general/link/component.rb +0 -258
  98. data/app/components/better_ui/general/modal/component.html.erb +0 -5
  99. data/app/components/better_ui/general/modal/component.rb +0 -47
  100. data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
  101. data/app/components/better_ui/general/modal/modal_component.rb +0 -160
  102. data/app/components/better_ui/general/pagination/component.html.erb +0 -85
  103. data/app/components/better_ui/general/pagination/component.rb +0 -216
  104. data/app/components/better_ui/general/panel/component.html.erb +0 -28
  105. data/app/components/better_ui/general/panel/component.rb +0 -249
  106. data/app/components/better_ui/general/progress/component.html.erb +0 -11
  107. data/app/components/better_ui/general/progress/component.rb +0 -160
  108. data/app/components/better_ui/general/spinner/component.html.erb +0 -35
  109. data/app/components/better_ui/general/spinner/component.rb +0 -93
  110. data/app/components/better_ui/general/table/component.html.erb +0 -5
  111. data/app/components/better_ui/general/table/component.rb +0 -217
  112. data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
  113. data/app/components/better_ui/general/table/tbody_component.rb +0 -30
  114. data/app/components/better_ui/general/table/td_component.html.erb +0 -3
  115. data/app/components/better_ui/general/table/td_component.rb +0 -44
  116. data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
  117. data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
  118. data/app/components/better_ui/general/table/th_component.html.erb +0 -6
  119. data/app/components/better_ui/general/table/th_component.rb +0 -51
  120. data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
  121. data/app/components/better_ui/general/table/thead_component.rb +0 -28
  122. data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
  123. data/app/components/better_ui/general/table/tr_component.rb +0 -30
  124. data/app/components/better_ui/general/tabs/component.html.erb +0 -11
  125. data/app/components/better_ui/general/tabs/component.rb +0 -120
  126. data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
  127. data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
  128. data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
  129. data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
  130. data/app/components/better_ui/general/tag/component.html.erb +0 -3
  131. data/app/components/better_ui/general/tag/component.rb +0 -104
  132. data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
  133. data/app/components/better_ui/general/tooltip/component.rb +0 -239
  134. data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
  135. data/app/helpers/better_ui/application/components/card.rb +0 -11
  136. data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
  137. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
  138. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
  139. data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
  140. data/app/helpers/better_ui/general/components/accordion.rb +0 -11
  141. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
  142. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
  143. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
  144. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
  145. data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
  146. data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
  147. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
  148. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
  149. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -79
  150. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -62
  151. data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
  152. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
  153. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
  154. data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
  155. data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
  156. data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
  157. data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
  158. data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -70
  159. data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
  160. data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
  161. data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
  162. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
  163. data/app/helpers/better_ui/general/components/modal.rb +0 -11
  164. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
  165. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
  166. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
  167. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
  168. data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
  169. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
  170. data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
  171. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
  172. data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
  173. data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
  174. data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
  175. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
  176. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
  177. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
  178. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
  179. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
  180. data/app/jobs/better_ui/application_job.rb +0 -4
  181. data/app/mailers/better_ui/application_mailer.rb +0 -6
  182. data/config/initializers/lookbook.rb +0 -23
  183. data/lib/better_ui/railtie.rb +0 -20
@@ -1,10 +0,0 @@
1
- <%# Template per il divider %>
2
- <% if show_label? %>
3
- <%= tag.div(**divider_attributes) do %>
4
- <div class="<%= label_line_classes %>"></div>
5
- <span class="<%= label_classes %>"><%= @label %></span>
6
- <div class="<%= label_line_classes %>"></div>
7
- <% end %>
8
- <% else %>
9
- <%= tag.div(**divider_attributes) %>
10
- <% end %>
@@ -1,226 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Divider
4
- class Component < ViewComponent::Base
5
- attr_reader :theme, :orientation, :style, :size, :label, :height, :classes
6
-
7
- # Classi base sempre presenti
8
- DIVIDER_BASE_CLASSES = "my-4"
9
-
10
- # Temi con classi Tailwind dirette - LOGICA CORRETTA
11
- DIVIDER_THEME_CLASSES = {
12
- default: "border-white", # Bordo bianco (per sfondi scuri)
13
- white: "border-gray-300", # Bordo grigio (per sfondi chiari)
14
- red: "border-red-500",
15
- rose: "border-rose-500",
16
- orange: "border-orange-500",
17
- green: "border-green-500",
18
- blue: "border-blue-500",
19
- yellow: "border-yellow-500",
20
- violet: "border-violet-500"
21
- }
22
-
23
- # Orientamento con classi Tailwind dirette
24
- DIVIDER_ORIENTATION_CLASSES = {
25
- horizontal: "w-full border-t",
26
- vertical: "h-full border-l"
27
- }
28
-
29
- # Stili di linea con classi Tailwind dirette
30
- DIVIDER_STYLE_CLASSES = {
31
- solid: "border-solid",
32
- dashed: "border-dashed",
33
- dotted: "border-dotted",
34
- double: "border-double"
35
- }
36
-
37
- # Dimensioni con classi Tailwind dirette
38
- DIVIDER_SIZE_CLASSES = {
39
- thin: {
40
- horizontal: "border-t",
41
- vertical: "border-l"
42
- },
43
- medium: {
44
- horizontal: "border-t-2",
45
- vertical: "border-l-2"
46
- },
47
- thick: {
48
- horizontal: "border-t-4",
49
- vertical: "border-l-4"
50
- }
51
- }
52
-
53
- # Classi per label con classi Tailwind dirette - LOGICA CORRETTA
54
- DIVIDER_LABEL_THEME_CLASSES = {
55
- default: "text-white bg-transparent px-3", # Testo bianco trasparente (per sfondi scuri)
56
- white: "text-gray-900 bg-white px-3", # Testo nero su bianco (per sfondi chiari)
57
- red: "text-red-500 bg-white px-3",
58
- rose: "text-rose-500 bg-white px-3",
59
- orange: "text-orange-500 bg-white px-3",
60
- green: "text-green-500 bg-white px-3",
61
- blue: "text-blue-500 bg-white px-3",
62
- yellow: "text-yellow-600 bg-white px-3",
63
- violet: "text-violet-500 bg-white px-3"
64
- }
65
-
66
- # @param theme [Symbol] tema del divider (:default, :white, etc.)
67
- # @param orientation [Symbol] orientamento del divider (:horizontal, :vertical)
68
- # @param style [Symbol] stile della linea (:solid, :dashed, :dotted, :double)
69
- # @param size [Symbol] dimensione della linea (:thin, :medium, :thick)
70
- # @param label [String] testo opzionale da mostrare al centro del divider
71
- # @param height [String] altezza per divider verticale (es. "100px", "100%")
72
- # @param classes [String] classi CSS aggiuntive
73
- # @param html_options [Hash] opzioni HTML per il container
74
- def initialize(
75
- theme: :white,
76
- orientation: :horizontal,
77
- style: :solid,
78
- size: :medium,
79
- label: nil,
80
- height: nil,
81
- classes: nil,
82
- **html_options
83
- )
84
- @theme = theme.to_sym
85
- @orientation = orientation.to_sym
86
- @style = style.to_sym
87
- @size = size.to_sym
88
- @label = label
89
- @height = height
90
- @classes = classes
91
- @html_options = html_options
92
-
93
- validate_params
94
- end
95
-
96
- # Combina tutte le classi per il container
97
- def combined_classes
98
- base_classes = []
99
-
100
- if @label.present? && @orientation == :horizontal
101
- # Per divider con label orizzontale: flex layout
102
- base_classes = [
103
- "flex items-center text-center",
104
- get_theme_class,
105
- get_style_class
106
- ]
107
- else
108
- # Per divider normale
109
- base_classes = [
110
- DIVIDER_BASE_CLASSES,
111
- get_orientation_class,
112
- get_theme_class,
113
- get_style_class,
114
- get_size_class
115
- ]
116
- end
117
-
118
- [ *base_classes, @classes, @html_options[:class] ].compact.join(" ")
119
- end
120
-
121
- # Classi per il label
122
- def label_classes
123
- return "" unless @label.present?
124
-
125
- [
126
- "relative z-10 text-sm font-medium",
127
- get_label_theme_class
128
- ].compact.join(" ")
129
- end
130
-
131
- # Classi per le linee before/after quando c'è un label
132
- def label_line_classes
133
- return "" unless @label.present? && @orientation == :horizontal
134
-
135
- [
136
- "flex-1 h-px",
137
- get_theme_class,
138
- get_style_class
139
- ].compact.join(" ")
140
- end
141
-
142
- # Genera gli attributi di stile inline necessari
143
- def inline_styles
144
- return nil unless @orientation == :vertical && @height.present?
145
- "height: #{@height};"
146
- end
147
-
148
- # Restituisce gli attributi per il divider
149
- def divider_attributes
150
- attrs = {
151
- class: combined_classes
152
- }
153
-
154
- # Aggiungi stile inline se presente
155
- attrs[:style] = inline_styles if inline_styles.present?
156
-
157
- # Aggiungi altri attributi HTML se presenti
158
- @html_options.except(:class).each do |key, value|
159
- attrs[key] = value
160
- end
161
-
162
- attrs
163
- end
164
-
165
- # Determina se mostrare il label
166
- def show_label?
167
- @label.present? && @orientation == :horizontal
168
- end
169
-
170
- private
171
-
172
- def get_theme_class
173
- DIVIDER_THEME_CLASSES[@theme] || DIVIDER_THEME_CLASSES[:white]
174
- end
175
-
176
- def get_orientation_class
177
- DIVIDER_ORIENTATION_CLASSES[@orientation] || DIVIDER_ORIENTATION_CLASSES[:horizontal]
178
- end
179
-
180
- def get_style_class
181
- DIVIDER_STYLE_CLASSES[@style] || DIVIDER_STYLE_CLASSES[:solid]
182
- end
183
-
184
- def get_size_class
185
- size_map = DIVIDER_SIZE_CLASSES[@size] || DIVIDER_SIZE_CLASSES[:medium]
186
- size_map[@orientation] || size_map[:horizontal]
187
- end
188
-
189
- def get_label_theme_class
190
- DIVIDER_LABEL_THEME_CLASSES[@theme] || DIVIDER_LABEL_THEME_CLASSES[:white]
191
- end
192
-
193
- def validate_params
194
- validate_theme
195
- validate_orientation
196
- validate_style
197
- validate_size
198
- end
199
-
200
- def validate_theme
201
- unless DIVIDER_THEME_CLASSES.keys.include?(@theme)
202
- raise ArgumentError, "Il tema deve essere uno tra: #{DIVIDER_THEME_CLASSES.keys.join(', ')}"
203
- end
204
- end
205
-
206
- def validate_orientation
207
- unless DIVIDER_ORIENTATION_CLASSES.keys.include?(@orientation)
208
- raise ArgumentError, "L'orientamento deve essere uno tra: #{DIVIDER_ORIENTATION_CLASSES.keys.join(', ')}"
209
- end
210
- end
211
-
212
- def validate_style
213
- unless DIVIDER_STYLE_CLASSES.keys.include?(@style)
214
- raise ArgumentError, "Lo stile deve essere uno tra: #{DIVIDER_STYLE_CLASSES.keys.join(', ')}"
215
- end
216
- end
217
-
218
- def validate_size
219
- unless DIVIDER_SIZE_CLASSES.keys.include?(@size)
220
- raise ArgumentError, "La dimensione deve essere una tra: #{DIVIDER_SIZE_CLASSES.keys.join(', ')}"
221
- end
222
- end
223
- end
224
- end
225
- end
226
- end
@@ -1,25 +0,0 @@
1
- <div class="relative inline-block <%= @classes %>"
2
- data-controller="bui-dropdown"
3
- data-bui-dropdown-open-value="false"
4
- <%= tag.attributes(@html_options.except(:class)) %>>
5
-
6
- <button type="button"
7
- class="inline-flex items-center justify-center border font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 transition-colors <%= dynamic_trigger_classes %>"
8
- data-bui-dropdown-target="trigger"
9
- data-action="click->bui-dropdown#toggle keydown->bui-dropdown#keydown"
10
- aria-expanded="false"
11
- aria-haspopup="true">
12
- <%= @trigger %>
13
- <%= bui_icon("chevron-down", size: :small, classes: "ml-2 -mr-1") %>
14
- </button>
15
-
16
- <div class="absolute z-50 mt-2 origin-top-right bg-white border border-gray-200 shadow-lg focus:outline-none <%= dynamic_menu_classes %>"
17
- data-bui-dropdown-target="menu"
18
- role="menu"
19
- aria-orientation="vertical"
20
- style="display: none;">
21
- <div class="py-1" role="none" data-action="click->bui-dropdown#itemClick">
22
- <%= content %>
23
- </div>
24
- </div>
25
- </div>
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Dropdown
6
- class Component < ViewComponent::Base
7
- include BetterUi::General::Components::Icon::IconHelper
8
-
9
- attr_reader :trigger, :position, :theme, :size, :rounded, :animation, :classes, :html_options
10
-
11
- # Classi base spostate nel template HTML per migliore leggibilità
12
-
13
- # Temi per il trigger del dropdown con classi Tailwind dirette
14
- DROPDOWN_TRIGGER_THEME = {
15
- default: "bg-white border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-blue-500",
16
- white: "bg-white border-gray-300 text-gray-900 hover:bg-gray-50 focus:ring-gray-500",
17
- red: "bg-red-600 border-red-600 text-white hover:bg-red-700 focus:ring-red-500",
18
- rose: "bg-rose-600 border-rose-600 text-white hover:bg-rose-700 focus:ring-rose-500",
19
- orange: "bg-orange-600 border-orange-600 text-white hover:bg-orange-700 focus:ring-orange-500",
20
- green: "bg-green-600 border-green-600 text-white hover:bg-green-700 focus:ring-green-500",
21
- blue: "bg-blue-600 border-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
22
- yellow: "bg-yellow-500 border-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500",
23
- violet: "bg-violet-600 border-violet-600 text-white hover:bg-violet-700 focus:ring-violet-500"
24
- }.freeze
25
-
26
- # Dimensioni del trigger con classi Tailwind dirette
27
- DROPDOWN_TRIGGER_SIZE = {
28
- small: "px-3 py-1.5 text-sm",
29
- medium: "px-4 py-2 text-sm",
30
- large: "px-6 py-3 text-base"
31
- }.freeze
32
-
33
- # Border radius con classi Tailwind dirette
34
- DROPDOWN_ROUNDED = {
35
- none: "rounded-none",
36
- small: "rounded-md",
37
- medium: "rounded-lg",
38
- large: "rounded-xl",
39
- full: "rounded-full"
40
- }.freeze
41
-
42
- # Posizioni del menu dropdown
43
- DROPDOWN_POSITION = {
44
- bottom: "top-full left-0",
45
- top: "bottom-full left-0",
46
- left: "top-0 right-full mr-2",
47
- right: "top-0 left-full ml-2"
48
- }.freeze
49
-
50
- # Animazioni del dropdown
51
- DROPDOWN_ANIMATION = {
52
- fade: "transition-opacity duration-150",
53
- slide: "transition-all duration-150 transform",
54
- none: ""
55
- }.freeze
56
-
57
- def initialize(
58
- trigger:,
59
- position: :bottom,
60
- theme: :default,
61
- size: :medium,
62
- rounded: :medium,
63
- animation: :fade,
64
- classes: nil,
65
- **html_options
66
- )
67
- @trigger = trigger
68
- @position = position.to_sym
69
- @theme = theme.to_sym
70
- @size = size.to_sym
71
- @rounded = rounded.to_sym
72
- @animation = animation.to_sym
73
- @classes = classes
74
- @html_options = html_options
75
-
76
- validate_params
77
- end
78
-
79
- # Restituisce solo le classi dinamiche per il trigger
80
- def dynamic_trigger_classes
81
- [
82
- get_trigger_theme_classes,
83
- get_trigger_size_classes,
84
- get_trigger_rounded_classes
85
- ].compact.join(" ")
86
- end
87
-
88
- # Restituisce solo le classi dinamiche per il menu
89
- def dynamic_menu_classes
90
- [
91
- get_position_classes,
92
- get_animation_classes,
93
- get_menu_rounded_classes
94
- ].compact.join(" ")
95
- end
96
-
97
- # Metodi per attributi rimossi - ora gestiti direttamente nel template HTML
98
-
99
- # Verifica se rendere il componente
100
- def render?
101
- @trigger.present?
102
- end
103
-
104
- private
105
-
106
- def get_trigger_theme_classes
107
- DROPDOWN_TRIGGER_THEME[@theme] || DROPDOWN_TRIGGER_THEME[:default]
108
- end
109
-
110
- def get_trigger_size_classes
111
- DROPDOWN_TRIGGER_SIZE[@size] || DROPDOWN_TRIGGER_SIZE[:medium]
112
- end
113
-
114
- def get_trigger_rounded_classes
115
- DROPDOWN_ROUNDED[@rounded] || DROPDOWN_ROUNDED[:medium]
116
- end
117
-
118
- def get_menu_rounded_classes
119
- DROPDOWN_ROUNDED[@rounded] || DROPDOWN_ROUNDED[:medium]
120
- end
121
-
122
- def get_position_classes
123
- DROPDOWN_POSITION[@position] || DROPDOWN_POSITION[:bottom]
124
- end
125
-
126
- def get_animation_classes
127
- DROPDOWN_ANIMATION[@animation] || DROPDOWN_ANIMATION[:fade]
128
- end
129
-
130
- def validate_params
131
- validate_theme
132
- validate_size
133
- validate_rounded
134
- validate_position
135
- validate_animation
136
- end
137
-
138
- def validate_theme
139
- unless DROPDOWN_TRIGGER_THEME.keys.include?(@theme)
140
- raise ArgumentError, "Il tema deve essere uno tra: #{DROPDOWN_TRIGGER_THEME.keys.join(', ')}"
141
- end
142
- end
143
-
144
- def validate_size
145
- unless DROPDOWN_TRIGGER_SIZE.keys.include?(@size)
146
- raise ArgumentError, "La dimensione deve essere una tra: #{DROPDOWN_TRIGGER_SIZE.keys.join(', ')}"
147
- end
148
- end
149
-
150
- def validate_rounded
151
- unless DROPDOWN_ROUNDED.keys.include?(@rounded)
152
- raise ArgumentError, "Il border radius deve essere uno tra: #{DROPDOWN_ROUNDED.keys.join(', ')}"
153
- end
154
- end
155
-
156
- def validate_position
157
- unless DROPDOWN_POSITION.keys.include?(@position)
158
- raise ArgumentError, "La posizione deve essere una tra: #{DROPDOWN_POSITION.keys.join(', ')}"
159
- end
160
- end
161
-
162
- def validate_animation
163
- unless DROPDOWN_ANIMATION.keys.include?(@animation)
164
- raise ArgumentError, "L'animazione deve essere una tra: #{DROPDOWN_ANIMATION.keys.join(', ')}"
165
- end
166
- end
167
- end
168
- end
169
- end
170
- end
@@ -1 +0,0 @@
1
- <div <%= tag.attributes(divider_attributes) %>></div>
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Dropdown
6
- class DividerComponent < ViewComponent::Base
7
- attr_reader :classes, :html_options
8
-
9
- # Classi base per il divisore del dropdown
10
- DROPDOWN_DIVIDER_CLASSES = "border-t border-gray-100 my-1"
11
-
12
- def initialize(classes: nil, **html_options)
13
- @classes = classes
14
- @html_options = html_options
15
- end
16
-
17
- # Combina tutte le classi per il divisore
18
- def divider_classes
19
- [
20
- DROPDOWN_DIVIDER_CLASSES,
21
- @classes
22
- ].compact.join(" ")
23
- end
24
-
25
- # Restituisce gli attributi per il divisore
26
- def divider_attributes
27
- attrs = {
28
- class: divider_classes,
29
- role: "separator"
30
- }
31
-
32
- @html_options.except(:class).each do |key, value|
33
- attrs[key] = value
34
- end
35
-
36
- attrs
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,6 +0,0 @@
1
- <<%= tag_name %> <%= tag.attributes(item_attributes) %>>
2
- <% if @icon.present? %>
3
- <span class="mr-3 flex-shrink-0"><%= bui_icon(@icon, classes: "h-5 w-5") %></span>
4
- <% end %>
5
- <%= @text %>
6
- </<%= tag_name %>>
@@ -1,119 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Dropdown
6
- class ItemComponent < ViewComponent::Base
7
- include BetterUi::General::Components::Icon::IconHelper
8
-
9
- attr_reader :text, :icon, :href, :theme, :disabled, :active, :classes, :html_options
10
-
11
- # Classi base per l'elemento del dropdown
12
- DROPDOWN_ITEM_BASE_CLASSES = "flex items-center w-full px-4 py-2 text-sm transition-colors"
13
-
14
- # Temi per gli elementi del dropdown con classi Tailwind dirette
15
- DROPDOWN_ITEM_THEME = {
16
- default: "text-gray-700 hover:bg-gray-100 hover:text-gray-900",
17
- white: "text-gray-900 hover:bg-gray-50",
18
- red: "text-red-700 hover:bg-red-50 hover:text-red-900",
19
- rose: "text-rose-700 hover:bg-rose-50 hover:text-rose-900",
20
- orange: "text-orange-700 hover:bg-orange-50 hover:text-orange-900",
21
- green: "text-green-700 hover:bg-green-50 hover:text-green-900",
22
- blue: "text-blue-700 hover:bg-blue-50 hover:text-blue-900",
23
- yellow: "text-yellow-700 hover:bg-yellow-50 hover:text-yellow-900",
24
- violet: "text-violet-700 hover:bg-violet-50 hover:text-violet-900"
25
- }.freeze
26
-
27
- # Stati per gli elementi del dropdown
28
- DROPDOWN_ITEM_STATE_DISABLED = "opacity-50 cursor-not-allowed pointer-events-none"
29
- DROPDOWN_ITEM_STATE_ACTIVE = "bg-gray-100 text-gray-900"
30
-
31
- def initialize(
32
- text:,
33
- icon: nil,
34
- href: nil,
35
- theme: :default,
36
- disabled: false,
37
- active: false,
38
- classes: nil,
39
- **html_options
40
- )
41
- @text = text
42
- @icon = icon
43
- @href = href
44
- @theme = theme.to_sym
45
- @disabled = disabled
46
- @active = active
47
- @classes = classes
48
- @html_options = html_options
49
-
50
- validate_params
51
- end
52
-
53
- # Combina tutte le classi per l'elemento
54
- def item_classes
55
- classes = [
56
- DROPDOWN_ITEM_BASE_CLASSES,
57
- get_theme_classes,
58
- @classes
59
- ]
60
-
61
- classes << DROPDOWN_ITEM_STATE_DISABLED if @disabled
62
- classes << DROPDOWN_ITEM_STATE_ACTIVE if @active
63
-
64
- classes.compact.join(" ")
65
- end
66
-
67
- # Restituisce gli attributi per l'elemento
68
- def item_attributes
69
- attrs = {
70
- class: item_classes,
71
- role: "menuitem",
72
- "data-bui-dropdown-target": "item"
73
- }
74
-
75
- if @href.present? && !@disabled
76
- attrs[:href] = @href
77
- end
78
-
79
- if @disabled
80
- attrs["aria-disabled"] = "true"
81
- attrs[:tabindex] = "-1"
82
- end
83
-
84
- @html_options.except(:class).each do |key, value|
85
- attrs[key] = value
86
- end
87
-
88
- attrs
89
- end
90
-
91
- # Determina se usare un link o un button
92
- def tag_name
93
- @href.present? && !@disabled ? :a : :button
94
- end
95
-
96
- # Verifica se rendere il componente
97
- def render?
98
- @text.present?
99
- end
100
-
101
- private
102
-
103
- def get_theme_classes
104
- DROPDOWN_ITEM_THEME[@theme] || DROPDOWN_ITEM_THEME[:default]
105
- end
106
-
107
- def validate_params
108
- validate_theme
109
- end
110
-
111
- def validate_theme
112
- unless DROPDOWN_ITEM_THEME.keys.include?(@theme)
113
- raise ArgumentError, "Il tema deve essere uno tra: #{DROPDOWN_ITEM_THEME.keys.join(', ')}"
114
- end
115
- end
116
- end
117
- end
118
- end
119
- end
@@ -1,27 +0,0 @@
1
- <%# Form field component template %>
2
- <div class="<%= BASE_CLASSES %>">
3
- <% if label.present? %>
4
- <label for="<%= id %>" class="<%= LABEL_CLASSES %>">
5
- <%= label %>
6
- <% if required %>
7
- <span class="<%= REQUIRED_CLASSES %>">*</span>
8
- <% end %>
9
- </label>
10
- <% end %>
11
-
12
- <div class="mt-1">
13
- <%= content %>
14
- </div>
15
-
16
- <% if error.present? %>
17
- <div class="<%= ERROR_CLASSES %>">
18
- <%= error %>
19
- </div>
20
- <% end %>
21
-
22
- <% if help_text.present? %>
23
- <div class="<%= HELP_TEXT_CLASSES %>">
24
- <%= help_text %>
25
- </div>
26
- <% end %>
27
- </div>
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Field
6
- class Component < ViewComponent::Base
7
- attr_reader :label, :name, :required, :error, :help_text, :id
8
-
9
- renders_one :input
10
-
11
- BASE_CLASSES = "flex flex-col space-y-2"
12
- LABEL_CLASSES = "text-sm font-medium text-gray-700"
13
- REQUIRED_CLASSES = "text-red-500 ml-1"
14
- ERROR_CLASSES = "text-sm text-red-600 mt-1"
15
- HELP_TEXT_CLASSES = "text-sm text-gray-500 mt-1"
16
-
17
- def initialize(label:, name:, required: false, error: nil, help_text: nil, id: nil)
18
- @label = label
19
- @name = name
20
- @required = required
21
- @error = error
22
- @help_text = help_text
23
- @id = id
24
- super()
25
- end
26
-
27
- private
28
-
29
- def field_classes
30
- classes = [BASE_CLASSES]
31
- classes << ERROR_CLASSES if @error.present?
32
- classes.join(" ")
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,22 +0,0 @@
1
- <%# Template per il heading %>
2
- <div class="<%= container_classes %>">
3
- <%= tag.public_send(heading_tag, **heading_attributes) do %>
4
- <% if show_icon? %>
5
- <span class="<%= icon_classes %>">
6
- <%= render BetterUi::General::IconComponent.new(name: @icon) %>
7
- </span>
8
- <% end %>
9
-
10
- <span><%= content %></span>
11
- <% end %>
12
-
13
- <% if show_subtitle? %>
14
- <div class="<%= subtitle_classes %>">
15
- <%= @subtitle %>
16
- </div>
17
- <% end %>
18
-
19
- <% if show_divider? %>
20
- <div class="<%= divider_classes %>"></div>
21
- <% end %>
22
- </div>