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,227 +0,0 @@
1
- <div data-controller="bui-sidebar"
2
- data-bui-sidebar-width-value="<%= @width == :md ? 256 : 320 %>"
3
- data-bui-sidebar-min-width-value="200"
4
- data-bui-sidebar-max-width-value="400"
5
- data-bui-sidebar-pinned-value="true">
6
-
7
- <!-- Mobile Overlay -->
8
- <div data-bui-sidebar-target="overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden md:hidden"></div>
9
-
10
- <!-- Sidebar Container -->
11
- <aside data-bui-sidebar-target="container" class="<%= container_classes %>">
12
- <!-- Header Section -->
13
- <% if has_header? %>
14
- <div class="px-6 py-4 border-b border-gray-200">
15
- <div class="flex items-center justify-between">
16
- <% if header[:logo].present? %>
17
- <div class="flex items-center">
18
- <div class="flex-shrink-0">
19
- <% if header[:logo].is_a?(Hash) %>
20
- <%= bui_avatar(**header[:logo]) %>
21
- <% else %>
22
- <%= header[:logo].html_safe %>
23
- <% end %>
24
- </div>
25
- <% if header[:title].present? %>
26
- <div class="ml-3">
27
- <h2 class="text-lg font-semibold text-gray-900"><%= header[:title] %></h2>
28
- <% if header[:subtitle].present? %>
29
- <p class="text-sm text-gray-500"><%= header[:subtitle] %></p>
30
- <% end %>
31
- </div>
32
- <% end %>
33
- </div>
34
- <% elsif header[:title].present? %>
35
- <div>
36
- <h2 class="text-lg font-semibold text-gray-900"><%= header[:title] %></h2>
37
- <% if header[:subtitle].present? %>
38
- <p class="text-sm text-gray-500"><%= header[:subtitle] %></p>
39
- <% end %>
40
- </div>
41
- <% end %>
42
-
43
- <!-- Collapse Button (solo se collapsible) -->
44
- <% if collapsible %>
45
- <%= bui_button(
46
- icon: "arrow-left",
47
- type: :white,
48
- size: :small,
49
- title: "Comprimi sidebar"
50
- ) %>
51
- <% end %>
52
- </div>
53
- </div>
54
- <% end %>
55
-
56
- <!-- Navigation Section -->
57
- <nav class="flex-1 px-4 py-6 space-y-6 overflow-y-auto">
58
- <% navigation_sections.each do |section| %>
59
- <div class="space-y-2">
60
- <!-- Section Title -->
61
- <% if section[:title].present? %>
62
- <% if section[:href] %>
63
- <%= link_to section[:href], class: "px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider" do %>
64
- <%= section[:title] %>
65
- <% end %>
66
- <% else %>
67
- <h3 class="px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider">
68
- <%= section[:title] %>
69
- </h3>
70
- <% end %>
71
- <% end %>
72
-
73
- <!-- Navigation Items -->
74
- <div class="space-y-1">
75
- <% (section[:items] || []).each do |item| %>
76
- <% if item[:type] == :collapsible && collapsible %>
77
- <!-- Collapsible Section -->
78
- <div>
79
- <button
80
- type="button"
81
- class="group flex items-center justify-between w-full px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50 hover:text-gray-900 transition-colors duration-150"
82
- data-bui-sidebar-target="sectionTrigger"
83
- data-bui-sidebar-section-id="<%= item[:id] %>"
84
- data-action="click->bui-sidebar#toggleSection"
85
- aria-expanded="<%= item[:expanded] || false %>"
86
- >
87
- <div class="flex items-center">
88
- <% if item[:icon].present? %>
89
- <span class="mr-3 text-gray-400 group-hover:text-gray-500">
90
- <%= bui_icon(item[:icon], size: :medium) %>
91
- </span>
92
- <% end %>
93
- <span><%= item[:label] %></span>
94
- </div>
95
- <span class="ml-3 transform transition-transform duration-150 <%= 'rotate-90' if item[:expanded] %>" data-bui-sidebar-chevron>
96
- <%= bui_icon("chevron-right", size: :small) %>
97
- </span>
98
- </button>
99
-
100
- <div
101
- data-bui-sidebar-target="sectionContent"
102
- data-bui-sidebar-section-id="<%= item[:id] %>"
103
- class="<%= item[:expanded] ? 'block' : 'hidden' %> mt-1 space-y-1"
104
- >
105
- <% (item[:children] || []).each do |child| %>
106
- <% if child[:href].present? %>
107
- <a
108
- href="<%= child[:href] %>"
109
- class="<%= (child[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %> pl-11"
110
- >
111
- <% if child[:icon].present? %>
112
- <span class="mr-3">
113
- <%= bui_icon(child[:icon], size: :small) %>
114
- </span>
115
- <% end %>
116
- <%= child[:label] %>
117
- </a>
118
- <% else %>
119
- <div class="<%= (child[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %> pl-11 cursor-default">
120
- <% if child[:icon].present? %>
121
- <span class="mr-3">
122
- <%= bui_icon(child[:icon], size: :small) %>
123
- </span>
124
- <% end %>
125
- <%= child[:label] %>
126
- </div>
127
- <% end %>
128
- <% end %>
129
- </div>
130
- </div>
131
- <% else %>
132
- <!-- Regular Navigation Item -->
133
- <% if item[:href].present? %>
134
- <a
135
- href="<%= item[:href] %>"
136
- class="<%= (item[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %>"
137
- >
138
- <% if item[:icon].present? %>
139
- <span class="mr-3 text-gray-400 group-hover:text-gray-500">
140
- <%= bui_icon(item[:icon], size: :medium) %>
141
- </span>
142
- <% end %>
143
- <%= item[:label] %>
144
- <% if item[:badge].present? %>
145
- <span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
146
- <%= item[:badge] %>
147
- </span>
148
- <% end %>
149
- </a>
150
- <% else %>
151
- <div class="<%= (item[:active] || false) ? 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 bg-gray-100 text-gray-900' : 'group flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors duration-150 text-gray-700 hover:bg-gray-50 hover:text-gray-900' %> cursor-default">
152
- <% if item[:icon].present? %>
153
- <span class="mr-3 text-gray-400">
154
- <%= bui_icon(item[:icon], size: :medium) %>
155
- </span>
156
- <% end %>
157
- <%= item[:label] %>
158
- <% if item[:badge].present? %>
159
- <span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
160
- <%= item[:badge] %>
161
- </span>
162
- <% end %>
163
- </div>
164
- <% end %>
165
- <% end %>
166
- <% end %>
167
- </div>
168
- </div>
169
- <% end %>
170
-
171
- <%= content if content.present? %>
172
- </nav>
173
-
174
- <!-- Footer Section -->
175
- <% if has_footer? %>
176
- <div class="px-6 py-4 border-t border-gray-200">
177
- <% if footer[:user_info].present? %>
178
- <div class="flex items-center">
179
- <% if footer[:user_info][:avatar].present? %>
180
- <div class="flex-shrink-0">
181
- <% if footer[:user_info][:avatar].is_a?(Hash) %>
182
- <%= bui_avatar(**footer[:user_info][:avatar]) %>
183
- <% else %>
184
- <%= footer[:user_info][:avatar].html_safe %>
185
- <% end %>
186
- </div>
187
- <% end %>
188
- <div class="<%= footer[:user_info][:avatar].present? ? 'ml-3' : '' %>">
189
- <% if footer[:user_info][:name].present? %>
190
- <p class="text-sm font-medium text-gray-700">
191
- <%= footer[:user_info][:name] %>
192
- </p>
193
- <% end %>
194
- <% if footer[:user_info][:email].present? %>
195
- <p class="text-xs text-gray-500">
196
- <%= footer[:user_info][:email] %>
197
- </p>
198
- <% end %>
199
- </div>
200
- <% if footer[:user_info][:menu_button].present? %>
201
- <div class="ml-auto">
202
- <%= footer[:user_info][:menu_button] %>
203
- </div>
204
- <% end %>
205
- </div>
206
- <% end %>
207
-
208
- <% if footer[:content].present? %>
209
- <div class="<%= footer[:user_info].present? ? 'mt-4' : '' %>">
210
- <%= footer[:content] %>
211
- </div>
212
- <% end %>
213
- </div>
214
- <% end %>
215
-
216
- <!-- Resize Handle (solo se NON collapsible) -->
217
- <% unless collapsible %>
218
- <div data-bui-sidebar-target="resizeHandle"
219
- class="absolute top-0 right-0 w-1 h-full bg-transparent hover:bg-blue-500 cursor-col-resize transition-colors duration-150 group">
220
- <div class="absolute inset-y-0 -right-1 w-3 flex items-center justify-center">
221
- <div class="w-0.5 h-8 bg-gray-300 group-hover:bg-blue-500 transition-colors duration-150"></div>
222
- </div>
223
- </div>
224
- <% end %>
225
- </aside>
226
-
227
- </div>
@@ -1,130 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module Application
5
- module Sidebar
6
- class Component < ViewComponent::Base
7
- # Include degli helper per utilizzare bui_icon, bui_avatar e bui_button
8
- include BetterUi::General::Components::Icon::IconHelper
9
- include BetterUi::General::Components::Avatar::AvatarHelper
10
- include BetterUi::General::Components::Button::ButtonHelper
11
- attr_reader :width, :position, :theme, :shadow, :border, :header, :footer, :navigation_sections, :collapsible, :classes
12
-
13
- # Larghezze sidebar con classi Tailwind dirette
14
- SIDEBAR_WIDTHS = {
15
- sm: "w-48",
16
- md: "w-64",
17
- lg: "w-72",
18
- xl: "w-80"
19
- }
20
-
21
- # Temi sidebar con classi Tailwind dirette
22
- SIDEBAR_THEMES = {
23
- default: "bg-white text-gray-900",
24
- dark: "bg-gray-900 text-white",
25
- light: "bg-white text-gray-900"
26
- }
27
-
28
- # Ombre sidebar con classi Tailwind dirette
29
- SIDEBAR_SHADOWS = {
30
- none: "",
31
- sm: "shadow-sm",
32
- md: "shadow-md",
33
- lg: "shadow-lg",
34
- xl: "shadow-xl"
35
- }
36
-
37
- # Bordi sidebar con classi Tailwind dirette
38
- SIDEBAR_BORDERS = {
39
- left: "border-r border-gray-200",
40
- right: "border-l border-gray-200"
41
- }
42
-
43
- # @param width [Symbol] Larghezza della sidebar (:sm, :md, :lg, :xl), default :md (w-64)
44
- # @param position [Symbol] Posizione della sidebar (:left, :right), default :left
45
- # @param theme [Symbol] Tema colori (:default, :dark, :light), default :default
46
- # @param shadow [Symbol] Tipo di ombra (:none, :sm, :md, :lg), default :lg
47
- # @param border [Boolean] Se mostrare il bordo destro/sinistro, default true
48
- # @param header [Hash] Configurazione header (logo, title, subtitle)
49
- # @param footer [Hash] Configurazione footer (content, user_info)
50
- # @param navigation_sections [Array] Array di sezioni di navigazione
51
- # @param collapsible [Boolean] Se abilitare sezioni collassabili, default true
52
- # @param classes [String] Classi CSS aggiuntive
53
- def initialize(
54
- width: :md,
55
- position: :left,
56
- theme: :default,
57
- shadow: :lg,
58
- border: true,
59
- header: {},
60
- footer: {},
61
- navigation_sections: [],
62
- collapsible: true,
63
- classes: nil
64
- )
65
- @width = width.to_sym
66
- @position = position.to_sym
67
- @theme = theme.to_sym
68
- @shadow = shadow.to_sym
69
- @border = border
70
- @header = header || {}
71
- @footer = footer || {}
72
- @navigation_sections = navigation_sections || []
73
- @collapsible = collapsible
74
- @classes = classes
75
- end
76
-
77
- def container_classes
78
- base_classes = %w[fixed inset-y-0 h-screen z-50 flex flex-col]
79
-
80
- # Posizione
81
- base_classes << (position == :right ? "right-0" : "left-0")
82
-
83
- # Larghezza
84
- base_classes << width_class
85
-
86
- # Tema
87
- base_classes.concat(theme_classes)
88
-
89
- # Shadow
90
- base_classes << shadow_class if shadow != :none
91
-
92
- # Border
93
- base_classes << border_class if border
94
-
95
- # Classi aggiuntive
96
- base_classes << classes if classes.present?
97
-
98
- base_classes.compact.join(" ")
99
- end
100
-
101
-
102
- def has_header?
103
- header.present? && (header[:title].present? || header[:logo].present?)
104
- end
105
-
106
- def has_footer?
107
- footer.present? && (footer[:content].present? || footer[:user_info].present?)
108
- end
109
-
110
- private
111
-
112
- def width_class
113
- SIDEBAR_WIDTHS[@width] || SIDEBAR_WIDTHS[:md]
114
- end
115
-
116
- def theme_classes
117
- (SIDEBAR_THEMES[@theme] || SIDEBAR_THEMES[:default]).split
118
- end
119
-
120
- def shadow_class
121
- SIDEBAR_SHADOWS[@shadow] || SIDEBAR_SHADOWS[:none]
122
- end
123
-
124
- def border_class
125
- SIDEBAR_BORDERS[@position] || SIDEBAR_BORDERS[:left]
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,5 +0,0 @@
1
- <div <%= tag.attributes(wrapper_attributes) %>>
2
- <% items.each do |item| %>
3
- <%= item %>
4
- <% end %>
5
- </div>
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Accordion
6
- class Component < ViewComponent::Base
7
- renders_many :items, "BetterUi::General::Accordion::ItemComponent"
8
-
9
- ACCORDION_THEME = {
10
- default: 'border-gray-200',
11
- white: 'border-gray-100 bg-white',
12
- blue: 'border-blue-200',
13
- red: 'border-red-200',
14
- green: 'border-green-200',
15
- yellow: 'border-yellow-200',
16
- violet: 'border-violet-200',
17
- orange: 'border-orange-200',
18
- rose: 'border-rose-200'
19
- }.freeze
20
-
21
- ACCORDION_VARIANT = {
22
- minimal: '',
23
- bordered: 'border rounded-lg',
24
- separated: 'space-y-2'
25
- }.freeze
26
-
27
- ACCORDION_SIZE = {
28
- small: 'text-sm',
29
- medium: 'text-base',
30
- large: 'text-lg'
31
- }.freeze
32
-
33
- def initialize(multiple: false, theme: :default, variant: :bordered, size: :medium,
34
- classes: '', **options)
35
- @multiple = multiple
36
- @theme = theme
37
- @variant = variant
38
- @size = size
39
- @classes = classes
40
- @options = options
41
-
42
- validate_params
43
- end
44
-
45
- private
46
-
47
- attr_reader :multiple, :theme, :variant, :size, :classes, :options
48
-
49
- def validate_params
50
- validate_theme
51
- validate_variant
52
- validate_size
53
- end
54
-
55
- def validate_theme
56
- return if ACCORDION_THEME.key?(theme)
57
-
58
- raise ArgumentError, "Invalid theme: #{theme}. Must be one of #{ACCORDION_THEME.keys}"
59
- end
60
-
61
- def validate_variant
62
- return if ACCORDION_VARIANT.key?(variant)
63
-
64
- raise ArgumentError, "Invalid variant: #{variant}. Must be one of #{ACCORDION_VARIANT.keys}"
65
- end
66
-
67
- def validate_size
68
- return if ACCORDION_SIZE.key?(size)
69
-
70
- raise ArgumentError, "Invalid size: #{size}. Must be one of #{ACCORDION_SIZE.keys}"
71
- end
72
-
73
- # Attributi per il wrapper principale
74
- def wrapper_attributes
75
- base_classes = [
76
- 'bui-accordion',
77
- ACCORDION_SIZE[size],
78
- ACCORDION_VARIANT[variant],
79
- ACCORDION_THEME[theme],
80
- classes
81
- ].compact.join(' ')
82
-
83
- {
84
- class: base_classes,
85
- 'data-controller': 'bui-accordion',
86
- 'data-bui-accordion-multiple-value': multiple
87
- }.merge(options)
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,12 +0,0 @@
1
- <div <%= tag.attributes(item_attributes) %>>
2
- <!-- Header -->
3
- <button <%= tag.attributes(header_attributes) %>>
4
- <span><%= title %></span>
5
- <i class="fas fa-<%= icon %> <%= icon_attributes[:class] %>" <%= tag.attributes(icon_attributes.except(:class)) %>></i>
6
- </button>
7
-
8
- <!-- Content -->
9
- <div <%= tag.attributes(content_attributes) %>>
10
- <%= content %>
11
- </div>
12
- </div>
@@ -1,176 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BetterUi
4
- module General
5
- module Accordion
6
- class ItemComponent < ViewComponent::Base
7
- ITEM_THEME = {
8
- default: 'border-gray-200 bg-white',
9
- white: 'border-gray-100 bg-white',
10
- blue: 'border-blue-200 bg-blue-50',
11
- red: 'border-red-200 bg-red-50',
12
- green: 'border-green-200 bg-green-50',
13
- yellow: 'border-yellow-200 bg-yellow-50',
14
- violet: 'border-violet-200 bg-violet-50',
15
- orange: 'border-orange-200 bg-orange-50',
16
- rose: 'border-rose-200 bg-rose-50'
17
- }.freeze
18
-
19
- ITEM_HEADER_THEME = {
20
- default: 'text-gray-900 hover:bg-gray-50',
21
- white: 'text-gray-900 hover:bg-gray-50',
22
- blue: 'text-blue-900 hover:bg-blue-100',
23
- red: 'text-red-900 hover:bg-red-100',
24
- green: 'text-green-900 hover:bg-green-100',
25
- yellow: 'text-yellow-900 hover:bg-yellow-100',
26
- violet: 'text-violet-900 hover:bg-violet-100',
27
- orange: 'text-orange-900 hover:bg-orange-100',
28
- rose: 'text-rose-900 hover:bg-rose-100'
29
- }.freeze
30
-
31
- ITEM_SIZE_HEADER = {
32
- small: 'text-sm px-4 py-3',
33
- medium: 'text-base px-5 py-4',
34
- large: 'text-lg px-6 py-5'
35
- }.freeze
36
-
37
- ITEM_SIZE_CONTENT = {
38
- small: 'px-4 py-3',
39
- medium: 'px-5 py-4',
40
- large: 'px-6 py-5'
41
- }.freeze
42
-
43
- ITEM_SIZE_ICON = {
44
- small: 'w-4 h-4',
45
- medium: 'w-5 h-5',
46
- large: 'w-6 h-6'
47
- }.freeze
48
-
49
- def initialize(title:, expanded: false, disabled: false, icon: 'chevron-down',
50
- theme: :default, size: :medium, classes: '', **options)
51
- @title = title
52
- @expanded = expanded
53
- @disabled = disabled
54
- @icon = icon
55
- @theme = theme
56
- @size = size
57
- @classes = classes
58
- @options = options
59
-
60
- validate_params
61
- end
62
-
63
- private
64
-
65
- attr_reader :title, :expanded, :disabled, :icon, :theme, :size, :classes, :options
66
-
67
- def validate_params
68
- validate_theme
69
- validate_size
70
-
71
- raise ArgumentError, 'title cannot be blank' if title.blank?
72
- end
73
-
74
- def validate_theme
75
- return if ITEM_THEME.key?(theme)
76
-
77
- raise ArgumentError, "Invalid theme: #{theme}. Must be one of #{ITEM_THEME.keys}"
78
- end
79
-
80
- def validate_size
81
- return if ITEM_SIZE_HEADER.key?(size)
82
-
83
- raise ArgumentError, "Invalid size: #{size}. Must be one of #{ITEM_SIZE_HEADER.keys}"
84
- end
85
-
86
- def unique_id
87
- @unique_id ||= "accordion-item-#{SecureRandom.hex(4)}"
88
- end
89
-
90
- def content_id
91
- "#{unique_id}-content"
92
- end
93
-
94
- def header_id
95
- "#{unique_id}-header"
96
- end
97
-
98
- # Attributi per il wrapper dell'item
99
- def item_attributes
100
- base_classes = [
101
- 'bui-accordion-item',
102
- ITEM_THEME[theme],
103
- classes
104
- ].compact.join(' ')
105
-
106
- {
107
- class: base_classes,
108
- 'data-bui-accordion-target': 'item'
109
- }.merge(options)
110
- end
111
-
112
- # Attributi per il button header
113
- def header_attributes
114
- base_classes = [
115
- 'bui-accordion-header',
116
- 'w-full flex items-center justify-between text-left font-medium transition-colors duration-200',
117
- ITEM_SIZE_HEADER[size],
118
- ITEM_HEADER_THEME[theme],
119
- disabled? ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'
120
- ].compact.join(' ')
121
-
122
- {
123
- class: base_classes,
124
- type: 'button',
125
- id: header_id,
126
- 'aria-expanded': expanded,
127
- 'aria-controls': content_id,
128
- 'data-action': 'click->bui-accordion#toggle',
129
- 'data-bui-accordion-target': 'trigger',
130
- disabled: disabled
131
- }
132
- end
133
-
134
- # Attributi per il contenuto
135
- def content_attributes
136
- base_classes = [
137
- 'bui-accordion-content',
138
- 'transition-all duration-300 ease-in-out overflow-hidden',
139
- ITEM_SIZE_CONTENT[size],
140
- expanded? ? 'block' : 'hidden'
141
- ].compact.join(' ')
142
-
143
- {
144
- class: base_classes,
145
- id: content_id,
146
- 'aria-labelledby': header_id,
147
- 'data-bui-accordion-target': 'content'
148
- }
149
- end
150
-
151
- # Attributi per l'icona
152
- def icon_attributes
153
- base_classes = [
154
- 'bui-accordion-icon',
155
- 'transition-transform duration-200',
156
- ITEM_SIZE_ICON[size],
157
- expanded? ? 'rotate-180' : ''
158
- ].compact.join(' ')
159
-
160
- {
161
- class: base_classes,
162
- 'data-bui-accordion-target': 'icon'
163
- }
164
- end
165
-
166
- def disabled?
167
- disabled
168
- end
169
-
170
- def expanded?
171
- expanded
172
- end
173
- end
174
- end
175
- end
176
- end
@@ -1,32 +0,0 @@
1
- <div <%= tag.attributes(alert_attributes) %>>
2
- <% if (@icon.blank? ? default_icon : @icon) && @icon_position == :left %>
3
- <div class="<%= get_icon_classes %> <%= get_icon_theme_class %>">
4
- <%= render BetterUi::General::Icon::Component.new(name: @icon.blank? ? default_icon : @icon) %>
5
- </div>
6
- <% end %>
7
-
8
- <div class="<%= get_content_classes %>">
9
- <% if @title.present? %>
10
- <div class="<%= ALERT_TITLE_CLASSES %>"><%= @title %></div>
11
- <% end %>
12
- <div class="<%= ALERT_MESSAGE_CLASSES %>">
13
- <% if @html_content %>
14
- <%= raw @message %>
15
- <% else %>
16
- <%= @message %>
17
- <% end %>
18
- </div>
19
- </div>
20
-
21
- <% if (@icon.blank? ? default_icon : @icon) && @icon_position == :right %>
22
- <div class="<%= get_icon_classes %> <%= get_icon_theme_class %>">
23
- <%= render BetterUi::General::Icon::Component.new(name: @icon.blank? ? default_icon : @icon) %>
24
- </div>
25
- <% end %>
26
-
27
- <% if @dismissible %>
28
- <button type="button" class="<%= get_close_classes %>" aria-label="Chiudi">
29
- <%= render BetterUi::General::Icon::Component.new(name: "x", size: :sm) %>
30
- </button>
31
- <% end %>
32
- </div>