better_ui 0.3.0 → 0.4.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.

Potentially problematic release.


This version of better_ui might be problematic. Click here for more details.

Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +174 -216
  4. data/app/assets/javascripts/better_ui/controllers/navbar_controller.js +138 -0
  5. data/app/assets/javascripts/better_ui/controllers/sidebar_controller.js +211 -0
  6. data/app/assets/javascripts/better_ui/controllers/toast_controller.js +161 -0
  7. data/app/assets/javascripts/better_ui/index.js +159 -0
  8. data/app/assets/javascripts/better_ui/toast_manager.js +77 -0
  9. data/app/assets/stylesheets/better_ui/application.css +30 -0
  10. data/app/components/better_ui/application/alert_component.html.erb +27 -0
  11. data/app/components/better_ui/application/alert_component.rb +196 -0
  12. data/app/components/better_ui/application/header_component.html.erb +88 -0
  13. data/app/components/better_ui/application/header_component.rb +188 -0
  14. data/app/components/better_ui/application/navbar_component.html.erb +294 -0
  15. data/app/components/better_ui/application/navbar_component.rb +249 -0
  16. data/app/components/better_ui/application/sidebar_component.html.erb +207 -0
  17. data/app/components/better_ui/application/sidebar_component.rb +318 -0
  18. data/app/components/better_ui/application/toast_component.html.erb +35 -0
  19. data/app/components/better_ui/application/toast_component.rb +188 -0
  20. data/app/components/better_ui/general/breadcrumb_component.html.erb +39 -0
  21. data/app/components/better_ui/general/breadcrumb_component.rb +132 -0
  22. data/app/components/better_ui/general/{button/component.html.erb → button_component.html.erb} +7 -7
  23. data/app/components/better_ui/general/button_component.rb +193 -0
  24. data/app/components/better_ui/general/heading_component.html.erb +25 -0
  25. data/app/components/better_ui/general/heading_component.rb +142 -0
  26. data/app/components/better_ui/general/icon_component.html.erb +2 -0
  27. data/app/components/better_ui/general/icon_component.rb +101 -0
  28. data/app/components/better_ui/general/panel_component.html.erb +27 -0
  29. data/app/components/better_ui/general/panel_component.rb +97 -0
  30. data/app/components/better_ui/general/table_component.html.erb +37 -0
  31. data/app/components/better_ui/general/table_component.rb +141 -0
  32. data/app/components/better_ui/theme_helper.rb +169 -0
  33. data/app/controllers/better_ui/application_controller.rb +1 -0
  34. data/app/controllers/better_ui/docs_controller.rb +34 -0
  35. data/app/helpers/better_ui_application_helper.rb +99 -0
  36. data/app/views/layouts/component_preview.html.erb +32 -0
  37. data/config/initializers/lookbook.rb +12 -12
  38. data/config/routes.rb +13 -0
  39. data/lib/better_ui/engine.rb +42 -5
  40. data/lib/better_ui/version.rb +1 -1
  41. data/lib/better_ui.rb +20 -4
  42. metadata +117 -157
  43. data/app/components/better_ui/application/card/component.html.erb +0 -20
  44. data/app/components/better_ui/application/card/component.rb +0 -214
  45. data/app/components/better_ui/application/main/component.html.erb +0 -9
  46. data/app/components/better_ui/application/main/component.rb +0 -123
  47. data/app/components/better_ui/application/navbar/component.html.erb +0 -92
  48. data/app/components/better_ui/application/navbar/component.rb +0 -136
  49. data/app/components/better_ui/application/sidebar/component.html.erb +0 -227
  50. data/app/components/better_ui/application/sidebar/component.rb +0 -130
  51. data/app/components/better_ui/general/accordion/component.html.erb +0 -5
  52. data/app/components/better_ui/general/accordion/component.rb +0 -92
  53. data/app/components/better_ui/general/accordion/item_component.html.erb +0 -12
  54. data/app/components/better_ui/general/accordion/item_component.rb +0 -176
  55. data/app/components/better_ui/general/alert/component.html.erb +0 -32
  56. data/app/components/better_ui/general/alert/component.rb +0 -242
  57. data/app/components/better_ui/general/avatar/component.html.erb +0 -20
  58. data/app/components/better_ui/general/avatar/component.rb +0 -301
  59. data/app/components/better_ui/general/badge/component.html.erb +0 -23
  60. data/app/components/better_ui/general/badge/component.rb +0 -248
  61. data/app/components/better_ui/general/breadcrumb/component.html.erb +0 -15
  62. data/app/components/better_ui/general/breadcrumb/component.rb +0 -187
  63. data/app/components/better_ui/general/button/component.rb +0 -214
  64. data/app/components/better_ui/general/divider/component.html.erb +0 -10
  65. data/app/components/better_ui/general/divider/component.rb +0 -226
  66. data/app/components/better_ui/general/dropdown/component.html.erb +0 -25
  67. data/app/components/better_ui/general/dropdown/component.rb +0 -170
  68. data/app/components/better_ui/general/dropdown/divider_component.html.erb +0 -1
  69. data/app/components/better_ui/general/dropdown/divider_component.rb +0 -41
  70. data/app/components/better_ui/general/dropdown/item_component.html.erb +0 -6
  71. data/app/components/better_ui/general/dropdown/item_component.rb +0 -119
  72. data/app/components/better_ui/general/field/component.html.erb +0 -27
  73. data/app/components/better_ui/general/field/component.rb +0 -37
  74. data/app/components/better_ui/general/heading/component.html.erb +0 -22
  75. data/app/components/better_ui/general/heading/component.rb +0 -257
  76. data/app/components/better_ui/general/icon/component.html.erb +0 -7
  77. data/app/components/better_ui/general/icon/component.rb +0 -239
  78. data/app/components/better_ui/general/input/checkbox/component.html.erb +0 -5
  79. data/app/components/better_ui/general/input/checkbox/component.rb +0 -238
  80. data/app/components/better_ui/general/input/datetime/component.html.erb +0 -5
  81. data/app/components/better_ui/general/input/datetime/component.rb +0 -223
  82. data/app/components/better_ui/general/input/radio/component.html.erb +0 -5
  83. data/app/components/better_ui/general/input/radio/component.rb +0 -230
  84. data/app/components/better_ui/general/input/select/component.html.erb +0 -16
  85. data/app/components/better_ui/general/input/select/component.rb +0 -184
  86. data/app/components/better_ui/general/input/select/select_component.html.erb +0 -5
  87. data/app/components/better_ui/general/input/select/select_component.rb +0 -37
  88. data/app/components/better_ui/general/input/text/component.html.erb +0 -5
  89. data/app/components/better_ui/general/input/text/component.rb +0 -171
  90. data/app/components/better_ui/general/input/textarea/component.html.erb +0 -5
  91. data/app/components/better_ui/general/input/textarea/component.rb +0 -166
  92. data/app/components/better_ui/general/link/component.html.erb +0 -18
  93. data/app/components/better_ui/general/link/component.rb +0 -258
  94. data/app/components/better_ui/general/modal/component.html.erb +0 -5
  95. data/app/components/better_ui/general/modal/component.rb +0 -47
  96. data/app/components/better_ui/general/modal/modal_component.html.erb +0 -52
  97. data/app/components/better_ui/general/modal/modal_component.rb +0 -160
  98. data/app/components/better_ui/general/pagination/component.html.erb +0 -85
  99. data/app/components/better_ui/general/pagination/component.rb +0 -216
  100. data/app/components/better_ui/general/panel/component.html.erb +0 -28
  101. data/app/components/better_ui/general/panel/component.rb +0 -249
  102. data/app/components/better_ui/general/progress/component.html.erb +0 -11
  103. data/app/components/better_ui/general/progress/component.rb +0 -160
  104. data/app/components/better_ui/general/spinner/component.html.erb +0 -35
  105. data/app/components/better_ui/general/spinner/component.rb +0 -93
  106. data/app/components/better_ui/general/table/component.html.erb +0 -5
  107. data/app/components/better_ui/general/table/component.rb +0 -217
  108. data/app/components/better_ui/general/table/tbody_component.html.erb +0 -3
  109. data/app/components/better_ui/general/table/tbody_component.rb +0 -30
  110. data/app/components/better_ui/general/table/td_component.html.erb +0 -3
  111. data/app/components/better_ui/general/table/td_component.rb +0 -44
  112. data/app/components/better_ui/general/table/tfoot_component.html.erb +0 -3
  113. data/app/components/better_ui/general/table/tfoot_component.rb +0 -28
  114. data/app/components/better_ui/general/table/th_component.html.erb +0 -6
  115. data/app/components/better_ui/general/table/th_component.rb +0 -51
  116. data/app/components/better_ui/general/table/thead_component.html.erb +0 -3
  117. data/app/components/better_ui/general/table/thead_component.rb +0 -28
  118. data/app/components/better_ui/general/table/tr_component.html.erb +0 -3
  119. data/app/components/better_ui/general/table/tr_component.rb +0 -30
  120. data/app/components/better_ui/general/tabs/component.html.erb +0 -11
  121. data/app/components/better_ui/general/tabs/component.rb +0 -120
  122. data/app/components/better_ui/general/tabs/panel_component.html.erb +0 -3
  123. data/app/components/better_ui/general/tabs/panel_component.rb +0 -37
  124. data/app/components/better_ui/general/tabs/tab_component.html.erb +0 -13
  125. data/app/components/better_ui/general/tabs/tab_component.rb +0 -111
  126. data/app/components/better_ui/general/tag/component.html.erb +0 -3
  127. data/app/components/better_ui/general/tag/component.rb +0 -104
  128. data/app/components/better_ui/general/tooltip/component.html.erb +0 -7
  129. data/app/components/better_ui/general/tooltip/component.rb +0 -239
  130. data/app/helpers/better_ui/application/components/card/card_helper.rb +0 -96
  131. data/app/helpers/better_ui/application/components/card.rb +0 -11
  132. data/app/helpers/better_ui/application/components/main/main_helper.rb +0 -64
  133. data/app/helpers/better_ui/application/components/navbar/navbar_helper.rb +0 -77
  134. data/app/helpers/better_ui/application/components/sidebar/sidebar_helper.rb +0 -51
  135. data/app/helpers/better_ui/application_helper.rb +0 -55
  136. data/app/helpers/better_ui/general/components/accordion/accordion_helper.rb +0 -73
  137. data/app/helpers/better_ui/general/components/accordion.rb +0 -11
  138. data/app/helpers/better_ui/general/components/alert/alert_helper.rb +0 -57
  139. data/app/helpers/better_ui/general/components/avatar/avatar_helper.rb +0 -29
  140. data/app/helpers/better_ui/general/components/badge/badge_helper.rb +0 -53
  141. data/app/helpers/better_ui/general/components/breadcrumb/breadcrumb_helper.rb +0 -37
  142. data/app/helpers/better_ui/general/components/button/button_helper.rb +0 -65
  143. data/app/helpers/better_ui/general/components/container/container_helper.rb +0 -60
  144. data/app/helpers/better_ui/general/components/divider/divider_helper.rb +0 -63
  145. data/app/helpers/better_ui/general/components/dropdown/divider_helper.rb +0 -32
  146. data/app/helpers/better_ui/general/components/dropdown/dropdown_helper.rb +0 -79
  147. data/app/helpers/better_ui/general/components/dropdown/item_helper.rb +0 -62
  148. data/app/helpers/better_ui/general/components/field/field_helper.rb +0 -26
  149. data/app/helpers/better_ui/general/components/heading/heading_helper.rb +0 -72
  150. data/app/helpers/better_ui/general/components/icon/icon_helper.rb +0 -16
  151. data/app/helpers/better_ui/general/components/input/checkbox/checkbox_helper.rb +0 -81
  152. data/app/helpers/better_ui/general/components/input/datetime/datetime_helper.rb +0 -91
  153. data/app/helpers/better_ui/general/components/input/radio/radio_helper.rb +0 -79
  154. data/app/helpers/better_ui/general/components/input/radio_group/radio_group_helper.rb +0 -124
  155. data/app/helpers/better_ui/general/components/input/select/select_helper.rb +0 -70
  156. data/app/helpers/better_ui/general/components/input/text/text_helper.rb +0 -138
  157. data/app/helpers/better_ui/general/components/input/textarea/textarea_helper.rb +0 -73
  158. data/app/helpers/better_ui/general/components/link/link_helper.rb +0 -89
  159. data/app/helpers/better_ui/general/components/modal/modal_helper.rb +0 -85
  160. data/app/helpers/better_ui/general/components/modal.rb +0 -11
  161. data/app/helpers/better_ui/general/components/pagination/pagination_helper.rb +0 -82
  162. data/app/helpers/better_ui/general/components/panel/panel_helper.rb +0 -83
  163. data/app/helpers/better_ui/general/components/progress/progress_helper.rb +0 -53
  164. data/app/helpers/better_ui/general/components/spinner/spinner_helper.rb +0 -19
  165. data/app/helpers/better_ui/general/components/table/table_helper.rb +0 -53
  166. data/app/helpers/better_ui/general/components/table/tbody_helper.rb +0 -13
  167. data/app/helpers/better_ui/general/components/table/td_helper.rb +0 -19
  168. data/app/helpers/better_ui/general/components/table/tfoot_helper.rb +0 -13
  169. data/app/helpers/better_ui/general/components/table/th_helper.rb +0 -19
  170. data/app/helpers/better_ui/general/components/table/thead_helper.rb +0 -13
  171. data/app/helpers/better_ui/general/components/table/tr_helper.rb +0 -13
  172. data/app/helpers/better_ui/general/components/tabs/panel_helper.rb +0 -62
  173. data/app/helpers/better_ui/general/components/tabs/tab_helper.rb +0 -55
  174. data/app/helpers/better_ui/general/components/tabs/tabs_helper.rb +0 -95
  175. data/app/helpers/better_ui/general/components/tag/tag_helper.rb +0 -26
  176. data/app/helpers/better_ui/general/components/tooltip/tooltip_helper.rb +0 -60
  177. data/app/views/layouts/better_ui/application.html.erb +0 -17
  178. data/lib/better_ui/railtie.rb +0 -20
@@ -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>
@@ -1,257 +0,0 @@
1
- module BetterUi
2
- module General
3
- module Heading
4
- class Component < ViewComponent::Base
5
- attr_reader :level, :theme, :align, :size, :style, :icon, :subtitle, :with_divider
6
-
7
- # Classi base sempre presenti
8
- HEADING_BASE_CLASSES = "font-bold leading-tight"
9
-
10
- # Temi con classi Tailwind dirette - LOGICA CORRETTA
11
- HEADING_THEME_CLASSES = {
12
- default: "text-white", # Testo bianco (per sfondi scuri)
13
- white: "text-gray-900", # Testo nero (per sfondi chiari)
14
- red: "text-red-500",
15
- rose: "text-rose-500",
16
- orange: "text-orange-500",
17
- green: "text-green-500",
18
- blue: "text-blue-500",
19
- yellow: "text-yellow-600",
20
- violet: "text-violet-500",
21
- purple: "text-purple-500"
22
- }
23
-
24
- # Allineamenti con classi Tailwind dirette
25
- HEADING_ALIGN_CLASSES = {
26
- left: "text-left",
27
- center: "text-center",
28
- right: "text-right"
29
- }
30
-
31
- # Dimensioni base (verranno combinate con level)
32
- HEADING_SIZE_CLASSES = {
33
- small: {
34
- 1 => "text-2xl sm:text-3xl",
35
- 2 => "text-xl sm:text-2xl",
36
- 3 => "text-lg sm:text-xl",
37
- 4 => "text-base sm:text-lg",
38
- 5 => "text-sm sm:text-base",
39
- 6 => "text-xs sm:text-sm"
40
- },
41
- medium: {
42
- 1 => "text-3xl sm:text-4xl",
43
- 2 => "text-2xl sm:text-3xl",
44
- 3 => "text-xl sm:text-2xl",
45
- 4 => "text-lg sm:text-xl",
46
- 5 => "text-base sm:text-lg",
47
- 6 => "text-sm sm:text-base"
48
- },
49
- large: {
50
- 1 => "text-4xl sm:text-5xl",
51
- 2 => "text-3xl sm:text-4xl",
52
- 3 => "text-2xl sm:text-3xl",
53
- 4 => "text-xl sm:text-2xl",
54
- 5 => "text-lg sm:text-xl",
55
- 6 => "text-base sm:text-lg"
56
- }
57
- }
58
-
59
- # Stili con classi Tailwind dirette
60
- HEADING_STYLE_CLASSES = {
61
- normal: "",
62
- bold: "font-extrabold",
63
- italic: "italic",
64
- underline: "underline"
65
- }
66
-
67
- # Temi per subtitle - LOGICA CORRETTA
68
- HEADING_SUBTITLE_THEME_CLASSES = {
69
- default: "text-gray-300", # Testo grigio chiaro (per sfondi scuri)
70
- white: "text-gray-600", # Testo grigio scuro (per sfondi chiari)
71
- red: "text-red-400",
72
- rose: "text-rose-400",
73
- orange: "text-orange-400",
74
- green: "text-green-400",
75
- blue: "text-blue-400",
76
- yellow: "text-yellow-500",
77
- violet: "text-violet-400"
78
- }
79
-
80
- # Temi per divider - LOGICA CORRETTA
81
- HEADING_DIVIDER_THEME_CLASSES = {
82
- default: "border-gray-700", # Bordo grigio scuro (per sfondi scuri)
83
- white: "border-gray-200", # Bordo grigio chiaro (per sfondi chiari)
84
- red: "border-red-200",
85
- rose: "border-rose-200",
86
- orange: "border-orange-200",
87
- green: "border-green-200",
88
- blue: "border-blue-200",
89
- yellow: "border-yellow-200",
90
- violet: "border-violet-200"
91
- }
92
-
93
- # @param level [Integer] livello del heading (1-6)
94
- # @param theme [Symbol] tema del colore (:default, :white, etc.)
95
- # @param align [Symbol] allineamento (:left, :center, :right)
96
- # @param size [Symbol] dimensione (:small, :medium, :large)
97
- # @param style [Symbol] stile (:normal, :bold, :italic, :underline)
98
- # @param icon [String] icona opzionale
99
- # @param subtitle [String] sottotitolo opzionale
100
- # @param with_divider [Boolean] mostra linea divisoria
101
- # @param html_options [Hash] opzioni HTML per il container
102
- def initialize(
103
- level: 2,
104
- theme: :white,
105
- align: :left,
106
- size: :medium,
107
- style: :normal,
108
- icon: nil,
109
- subtitle: nil,
110
- with_divider: false,
111
- **html_options
112
- )
113
- @level = level.to_i.clamp(1, 6)
114
- @theme = theme.to_sym
115
- @align = align.to_sym
116
- @size = size.to_sym
117
- @style = style.to_sym
118
- @icon = icon
119
- @subtitle = subtitle
120
- @with_divider = with_divider
121
- @html_options = html_options
122
-
123
- validate_params
124
- end
125
-
126
- # Combina tutte le classi per il heading
127
- def heading_classes
128
- [
129
- HEADING_BASE_CLASSES,
130
- get_theme_class,
131
- get_align_class,
132
- get_size_class,
133
- get_style_class,
134
- @html_options[:class]
135
- ].compact.join(" ")
136
- end
137
-
138
- # Classi per il container principale
139
- def container_classes
140
- "mb-4"
141
- end
142
-
143
- # Classi per il subtitle
144
- def subtitle_classes
145
- return "" unless @subtitle.present?
146
-
147
- [
148
- "mt-1 text-sm",
149
- get_subtitle_theme_class,
150
- get_align_class
151
- ].compact.join(" ")
152
- end
153
-
154
- # Classi per il divider
155
- def divider_classes
156
- return "" unless @with_divider
157
-
158
- [
159
- "mt-2 border-t",
160
- get_divider_theme_class
161
- ].compact.join(" ")
162
- end
163
-
164
- # Classi per l'icona
165
- def icon_classes
166
- return "" unless @icon.present?
167
- "mr-2 inline-block"
168
- end
169
-
170
- # Restituisce gli attributi HTML per il heading
171
- def heading_attributes
172
- attrs = @html_options.except(:class)
173
- attrs[:class] = heading_classes
174
- attrs
175
- end
176
-
177
- # Tag del heading basato sul level
178
- def heading_tag
179
- "h#{@level}"
180
- end
181
-
182
- # Determina se mostrare l'icona
183
- def show_icon?
184
- @icon.present?
185
- end
186
-
187
- # Determina se mostrare il subtitle
188
- def show_subtitle?
189
- @subtitle.present?
190
- end
191
-
192
- # Determina se mostrare il divider
193
- def show_divider?
194
- @with_divider
195
- end
196
-
197
- private
198
-
199
- def get_theme_class
200
- HEADING_THEME_CLASSES[@theme] || HEADING_THEME_CLASSES[:white]
201
- end
202
-
203
- def get_align_class
204
- HEADING_ALIGN_CLASSES[@align] || HEADING_ALIGN_CLASSES[:left]
205
- end
206
-
207
- def get_size_class
208
- size_map = HEADING_SIZE_CLASSES[@size] || HEADING_SIZE_CLASSES[:medium]
209
- size_map[@level] || size_map[2]
210
- end
211
-
212
- def get_style_class
213
- HEADING_STYLE_CLASSES[@style] || HEADING_STYLE_CLASSES[:normal]
214
- end
215
-
216
- def get_subtitle_theme_class
217
- HEADING_SUBTITLE_THEME_CLASSES[@theme] || HEADING_SUBTITLE_THEME_CLASSES[:white]
218
- end
219
-
220
- def get_divider_theme_class
221
- HEADING_DIVIDER_THEME_CLASSES[@theme] || HEADING_DIVIDER_THEME_CLASSES[:white]
222
- end
223
-
224
- def validate_params
225
- validate_theme
226
- validate_align
227
- validate_size
228
- validate_style
229
- end
230
-
231
- def validate_theme
232
- unless HEADING_THEME_CLASSES.keys.include?(@theme)
233
- raise ArgumentError, "Il tema deve essere uno tra: #{HEADING_THEME_CLASSES.keys.join(', ')}"
234
- end
235
- end
236
-
237
- def validate_align
238
- unless HEADING_ALIGN_CLASSES.keys.include?(@align)
239
- raise ArgumentError, "L'allineamento deve essere uno tra: #{HEADING_ALIGN_CLASSES.keys.join(', ')}"
240
- end
241
- end
242
-
243
- def validate_size
244
- unless HEADING_SIZE_CLASSES.keys.include?(@size)
245
- raise ArgumentError, "La dimensione deve essere una tra: #{HEADING_SIZE_CLASSES.keys.join(', ')}"
246
- end
247
- end
248
-
249
- def validate_style
250
- unless HEADING_STYLE_CLASSES.keys.include?(@style)
251
- raise ArgumentError, "Lo stile deve essere uno tra: #{HEADING_STYLE_CLASSES.keys.join(', ')}"
252
- end
253
- end
254
- end
255
- end
256
- end
257
- end
@@ -1,7 +0,0 @@
1
- <% if href.present? %>
2
- <%= tag.a(**icon_attributes) do %>
3
- <i class="<%= fa_class_name %> <%= icon_classes %>"></i>
4
- <% end %>
5
- <% else %>
6
- <i class="<%= fa_class_name %> <%= icon_classes %>"></i>
7
- <% end %>